Почему этот пробный тест не проходит? - PullRequest
0 голосов
/ 21 апреля 2020

Я пытаюсь смоделировать document.clipboard.

Вот мой код:

  handleCopyIdToClipboard = () => {
    const el = document.querySelector(`.${CLASS_NAME}`);
    navigator.clipboard.writeText(el.textContent);

    // some extra code
    showPopup();
  };

Вот мой тест на шутку:

describe('handleCopyToClipboard', () => {
const mockQuerySelector = jest.fn();
const mockBoundingClientRect = jest.fn();
const mockClipboard = jest.fn();
const mockWriteText = jest.fn();

mockQuerySelector.mockReturnValue({textContent: 'someText', getBoundingClientRect: mockBoundingClientRect});
mockBoundingClientRect.mockReturnValue({top: 100, left: 100});

Object.defineProperty(document, 'querySelector', {value: mockQuerySelector});
Object.defineProperty(navigator, 'clipboard', {value: mockClipboard});
Object.defineProperty(navigator.clipboard, 'writeText', {value: mockWriteText});

beforeEach(() =>
  [mockQuerySelector, mockClipboard, mockWriteText, mockBoundingClientRect].map(mock =>
    mock.mockClear(),
  ),
);

it('should copy to clipboard', () => {
  const wrapper = buildComponent(DetailsPage, props);
  wrapper.instance().handleCopyIdToClipboard('id');

  expect(mockQuerySelector).toHaveBeenCalled();
  expect(mockClipboard).toHaveBeenCalled();
  expect(mockWriteText).toHaveBeenCalled();
  expect(mockBoundingClientRect).toHaveBeenCalled();
  expect(wrapper.state().showPopup).toEqual(true);
  expect(wrapper.state().top).toEqual(90);
  expect(wrapper.state().left).toEqual(200);
});

});

Эта строка завершается с ошибкой expect(mockClipboard).toHaveBeenCalled();, указывая, что mockClipboard никогда не вызывается. Но если я уберу эту строку, expect(mockWriteText).toHaveBeenCalled(); не потерпит неудачу. Любая идея?

Редактировать:

Я обновил свою функцию до следующего:

  handleCopyIdToClipboard = () => {
    navigator.clipboard
      .writeText(this.state.urn)
      .then(() => {
        this.setState({showPopup: true});
      })
      .catch(doNothing);
  };

и текущий шутник:

  describe('handleCopyToClipboard', () => {
    const mockClipboard = jest.fn();
    const mockWriteText = jest.fn();

    Object.defineProperty(navigator, 'clipboard', {value: mockClipboard});
    Object.defineProperty(navigator.clipboard, 'writeText', {value: mockWriteText});

    beforeEach(() => [mockClipboard, mockWriteText].map(mock => mock.mockClear()));

  it('should copy to clipboard', () => {
    const wrapper = buildComponent(ServiceAccountDetailsPage, props);

    mockWriteText.mockReturnValueOnce(true);

    return wrapper
        .instance()
        .handleCopyIdToClipboard()
        .then(() => {
          expect(mockWriteText).toHaveBeenCalled();
          expect(wrapper.state().showPopup).toEqual(true);
        });
  });
});

работает в эту ошибку: navigator.clipboard.writeText(...).then is not a function. Я хотел бы протестировать блоки .then() и .catch()

1 Ответ

0 голосов
/ 22 апреля 2020

Navigator.clipboard не является функцией, вы не должны издеваться над ней как над функцией. Вы должны издеваться над всем clipboard объектом. Например,

main.ts:

export function handleCopyIdToClipboard() {
  const el = document.querySelector('.class-name');
  const textContent = el ? el.textContent || '' : '';
  return navigator.clipboard.writeText(textContent);
}

main.test.ts:

import { handleCopyIdToClipboard } from './main';

describe('61348091', () => {
  it('should pass', async () => {
    const mElement = { textContent: 'hello' };
    const mockQuerySelector = jest.fn().mockReturnValueOnce(mElement);
    const mockWriteText = jest.fn().mockResolvedValueOnce('clipText');
    Object.defineProperty(document, 'querySelector', { value: mockQuerySelector });
    Object.defineProperty(navigator, 'clipboard', {
      value: {
        writeText: mockWriteText,
      },
    });
    const actual = await handleCopyIdToClipboard();
    expect(actual).toBe('clipText');
    expect(mockQuerySelector).toBeCalledWith('.class-name');
    expect(mockWriteText).toBeCalledWith('hello');
  });
});

Результаты модульных испытаний с отчетом о покрытии:

 PASS  stackoverflow/61348091/main.test.ts (16.222s)
  61348091
    ✓ should pass (6ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |       50 |     100 |     100 |                   
 main.ts  |     100 |       50 |     100 |     100 | 3                 
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        18.23s
...