#javascript #node.js #unit-testing #reactjs #jestjs
#javascript #node.js #модульное тестирование #reactjs #jestjs
Вопрос:
Я пытаюсь выполнить модульное тестирование функции с помощью Jest, и у меня возникли некоторые проблемы с модулями jest-макетов (эквивалент rewire или proxyquire в мире nodejs).
Я на самом деле пытаюсь проверить, что в издевательском модуле был вызван шпион с некоторыми параметрами. Вот функция, которую я хочу протестировать.
ПРИМЕЧАНИЕ: текущий тест касается только части «fetch (…)», я пытаюсь проверить, что fetch был вызван с параметром good.
export const fetchRemote = slug => {
return dispatch => {
dispatch(loading());
return fetch(Constants.URL slug)
.then(res => res.json())
.then(cmp => {
if (cmp.length === 1) {
return dispatch(setCurrent(cmp[0]));
}
return dispatch(computeRemote(cmp));
});
};
};
Возвращаемая функция действует как замыкание и, таким образом, «захватывает» внешний модуль выборки узлов, который я хочу издеваться.
Вот тест, который я пытаюсь сделать зеленым :
it('should have called the fetch function wih the good const parameter and slug', done => {
const slug = 'slug';
const spy = jasmine.createSpy();
const stubDispatch = () => Promise.resolve({json: () => []});
jest.mock('node-fetch', () => spy);
const dispatcher = fetchRemote(slug);
dispatcher(stubDispatch).then(() => {
expect(spy).toHaveBeenCalledWith(Constants.URL slug);
done();
});
});
РЕДАКТИРОВАТЬ: первый ответ очень помог в написании теста, теперь у меня есть следующий :
it('should have called the fetch function wih the good const parameter and slug', done => {
const slug = 'slug';
const stubDispatch = () => null;
const spy = jest.mock('node-fetch', () => Promise.resolve({json: () => []}));
const dispatcher = fetchRemote(slug);
dispatcher(stubDispatch).then(() => {
expect(spy).toHaveBeenCalledWith(Constants.URL slug);
done();
});
});
Но теперь, вот ошибка, которая у меня есть :
console.error node_modules/core-js/modules/es6.promise.js:117
Unhandled promise rejection [Error: expect(jest.fn())[.not].toHaveBeenCalledWith()
jest.fn() value must be a mock function or spy.
Received:
object: {"addMatchers": [Function anonymous], "autoMockOff": [Function anonymous], "autoMockOn": [Function anonymous], "clearAllMocks": [Function anonymous], "clearAllTimers": [Function anonymous], "deepUnmock": [Function anonymous], "disableAutomock": [Function anonymous], "doMock": [Function anonymous], "dontMock": [Function anonymous], "enableAutomock": [Function anonymous], "fn": [Function anonymous], "genMockFn": [Function bound getMockFunction], "genMockFromModule": [Function anonymous], "genMockFunction": [Function bound getMockFunction], "isMockFunction": [Function isMockFunction], "mock": [Function anonymous], "resetModuleRegistry": [Function anonymous], "resetModules": [Function anonymous], "runAllImmediates": [Function anonymous], "runAllTicks": [Function anonymous], "runAllTimers": [Function anonymous], "runOnlyPendingTimers": [Function anonymous], "runTimersToTime": [Function anonymous], "setMock": [Function anonymous], "unmock": [Function anonymous], "useFakeTimers": [Function anonymous], "useRealTimers": [Function anonymous]}]
Ответ №1:
Прежде всего, вам нужно вернуть обещание при тестировании асинхронного кода. И ваш шпион должен вернуть разрешенное или отклоненное обещание.
it('should have called the fetch function wih the good const parameter and slug', done => {
const slug = 'successPath';
const stubDispatch = () => Promise.resolve({ json: () => [] });
spy = jest.mock('node-fetch', (path) => {
if (path === Constants.URL 'successPath') {
return Promise.resolve('someSuccessData ')
} else {
return Promise.reject('someErrorData')
}
});
const dispatcher = fetchRemote(slug);
return dispatcher(stubDispatch).then(() => {
expect(spy).toHaveBeenCalledWith(Constants.URL slug);
done();
});
});
Комментарии:
1. Я не вижу шпиона в этой реализации:/. Но спасибо за ваш ответ
2. Вы пробовали
expect(spy.mock)
вместоexpect(spy)
?3. И вы должны вернуть диспетчера из своего теста.
4. Я пробовал, но безуспешно. И кажется, что модуль узла вообще не издевается. Когда я запускаю свой тест без своего бэкэнда, он отправляет запрос и выдает ошибки
5. Итак, как вы импортируете
fetch
в свой модуль или используете собственную реализацию JS?