Jestjs как проверить функцию, вызываемую внутри другой функции
Для тестирования я использую jest и реагировать на тестирование. Это должно быть просто проверить, однако мне трудно найти подходящий пример. Я пытался сделать что-то подобное (в общем, я храню функции в отдельных файлах):
utils.js
export const childFunction = () => 'something';
const parentFunction = () => childFunction();
export default parentFunction;
utils.test.js
import parentFunction from './utils.js';
it('childFunction should be called', () => {
const childFunction = jest.fn();
parentFunction();
expect(childFunction).toBeCalled();
})
Фрагмент const childFunction = jest.fn(); определенно не будет работать. При вызове тело parentFunction заботится только о своей области видимости. Но это также не сработает, если я импортирую childFunction и выполняю jest.mock (childFunction), потому что jest.mock нужна строка, URL-адрес модуля, а не сама функция.
Приведенный выше пример не работает, и я ищу альтернативу. Однако это работает после ShallowRender React Component. И я хотел бы добиться аналогичного поведения с помощью функции, вложенной в другую функцию.
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
экспортируется, поэтому вы не можете получить ссылку на него и смоделировать / заглушки.
один обходной путь, который у вас есть, состоит в том, чтобы перенести его в свой собственный метод
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'); }
component.js делает:
import { parentFunction } from './utils';
Вы могли бы в своих тестах сделать:
const utils = require('./utils');
utils.parentFunction = jest.fn();
import Component from './component';
// later
expect(utils.parentFunction).toHaveBeenCalled();
как вы можете видеть, существует много возможных путей, хотя я не уверен в ценности этого теста, вам, вероятно, следует проверить вывод / функциональность компонента, а не его вызова, чтобы что-то выполнялось componentDidMount
является данным и сломался бы, только если кто-то перешел на функционал или изменил имя жизненного цикла.