Как имитировать созданный объект с помощью Jest

#javascript #testing #mocking #jestjs

#javascript #тестирование #издевательство #jestjs

Вопрос:

У меня есть файл (src / dclient), который делает это:

 import DataClient from 'src/clients/data'

const DClient = new DataClient({ id: 'xxx' })
export default DClient
  

И у меня есть файл (который я пытаюсь протестировать), который делает это:

 import DClient from src/dclient

// Some code

DClient.alert('hello')
  

Я пытаюсь записать ожидания на Dclient.alert , но не могу этого сделать. Я попытался настроить тест jest как:

 alertMock = jest.fn();
require('src/dclient').alert = alertMock
  

Но это не работает, когда я проверяю alertMock.mock.calls , хотя я знаю, что он был вызван. Я думаю, потому что dclient возвращает экземпляр и на самом деле для него не определено оповещение.

Как я могу настроить этот jest, чтобы я мог записывать ожидания при оповещении?

Ответ №1:

Есть несколько способов проверить это.

Способ, который вы пытаетесь использовать, работает нормально, вам просто нужно изменить его на этот:

 test('code', () => {
  const alertMock = jest.fn();
  require('src/dclient').default.alert = alertMock;  // <= mock alert on 'default'

  require('./code');  //  <= require the code that calls DClient.alert('hello')
  expect(alertMock).toHaveBeenCalledWith('hello');  // Success!
})
  

…потому что src/dclient это модуль ES6 с default экспортом.


Подход, который я бы, вероятно, использовал, заключается в том, чтобы имитировать alert функцию в DataClient классе:

 import DataClient from 'src/clients/data';

test('code', () => {
  const alertSpy = jest.spyOn(DataClient.prototype, 'alert');
  alertSpy.mockImplementation(() => {});

  require('./code');  //  <= require the code that calls DClient.alert('hello')
  expect(alertSpy).toHaveBeenCalledWith('hello');  // Success!
})
  

Комментарии:

1. Я использовал require(‘src / dclient’). alert = alertMock и я должен был выполнять require(‘src / dclient’).default.alert. Спасибо!

Ответ №2:

В Jest есть действительно хорошо выполненная функция автоматического издевательства, которая генерирует jest.fn() для каждого метода экспортируемого объекта, так что вы можете просто:

 import DClient from 'src/dclient'; // import the module
jest.mock('src/dclient'); // generate auto-mock

describe('alert', () => {
    beforeAll(() => {
        DClient.alert.mockReturnValue(true);
        // ^ not really needed in the alert case, but you'll get
        // error if the exported object doesn't have alert method
    });

    it('should have been called', () => {
        DClient.alert('hello');
        expect(DClient.alert).toHaveBeenCalledWith()
    });
});
  

Комментарии:

1. При выполнении этого я получаю эту ошибку jest.fn() value must be a mock function or spy

2. Обратите внимание, что DClient возвращает экземпляр другого файла… Разве это не изменило бы способ издевательства над ним?