#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 возвращает экземпляр другого файла… Разве это не изменило бы способ издевательства над ним?