Jestjs как проверить функцию, вызываемую внутри другой функции
Для тестирования я использую jest и react-test-renderer. Это должно быть просто проверить, однако мне трудно найти правильный пример. Я попытался сделать что-то вроде этого (в общем, я храню функции в отдельных файлах):
Utils.js
export const childFunction = () => 'something';
const parentFunction = () => childFunction();
export default parentFunction;
Utils.тест.js
import parentFunction from './utils.js';
it('childFunction should be called', () => {
const childFunction = jest.fn();
parentFunction();
expect(childFunction).toBeCalled();
})
Фрагмент const childFunction = jest.fn (); определенно не будет работать. Во время вызова тело родительской функции заботится только о своем собственном объеме. Но это также не будет работать, если я импортирую childFunction и сделайте шутку.mock (childFunction) , потому что шутка.макету нужна строка, url-адрес модуля, а не сама функция.
Приведенный выше пример не работает, и я ищу альтернативу. Однако это работает после компонента Shallowrender React. И я хотел бы добиться аналогичного поведения с функцией, вложенной в другую функцию.
class Component extends React.Component {
componentDidMount() {parentFunction()}
render() {...}
}
const renderer = new ShallowRenderer();
describe("testing parentFunction", () => {
renderer.render(<Component/>);
it("parentFunction should be called", () => {
expect(parentFunction).toBeCalled();
});
});
2 ответа:
Невозможно следить за вызовом функции, если функция не вызывается как метод объекта.
Как объяснено в Этот ответ, из-за того, как работают модули ES, можно шпионить или имитировать функцию, только если она была экспортирована из модуля и используется в другом модуле. Таким образом, он может быть подсмотрен на объекте модуля
*
или высмеян с помощьюjest.mock
.Если это не так, его следует проверить косвенно:
expect(childFunction()).toBe('something'); expect(parentFunction()).toBe('something');
Не уверен, что это поможет, но это может дать вам идеи.
Во-первых, приведенный выше пример:
// this needs to be stubbed // const childFunction = () => 'something'; const childFunction = jest.fn(); const parentFunction = () => childFunction(); it('childFunction should be called', () => { parentFunction(); expect(childFunction).toHaveBeenCalled(); }
Это несколько надуманный пример, поскольку маловероятно, что
childFunction
экспортируется, поэтому вы не можете получить ссылку на него и подделать/заглушить его.Один обходной путь, который вы должны были бы переместить его в свой собственный метод
Это позволяет создать прокол и шпионить за компонентом proto.class Component extends React.Component { componentDidMount() { this.parentFunction(); } parentFunction() { parentFunction(); // from elsewhere } render() {...} }
Например
const spy = jest.spyOn(Component.prototype, 'parentFunction'); // ... mount so lifecycle runs... expect(spy).toHaveBeenCalled(); // and clear the spy mocks after!
Может быть, лучше поиздеваться над модулем
Например у вас есть utils.js используется вашим компонентом, который делает:
export function parentFunction(){ console.log('parent'); }
Компонент.js делает:
import { parentFunction } from './utils';
Вы могли бы в своих тестах сделать:
const utils = require('./utils'); utils.parentFunction = jest.fn(); import Component from './component'; // later expect(utils.parentFunction).toHaveBeenCalled();
Как вы можете видеть, есть много возможных способов пойти, хотя я не уверен в значении этого теста, вы, вероятно, должны проверить выход / функциональность компонента, а не то, что он вызвал, имея что-то запущенное на
componentDidMount
является заданным и только сломается, если кто-то преобразуется в функциональный или изменяет имя жизненного цикла.