Слежка за методом функциональных компонентов React с помощью шутки и энзима; Невозможно шпионить за примитивным значением
Я пытаюсь протестировать компонент React и убедиться, что при нажатии его кнопки вызывается правильный метод. Однако когда я пытаюсь запустить свой тест и попытаться шпионить за этим методом, я получаю следующее сообщение:
Ошибка: невозможно шпионить за примитивным значением; неопределенный данный
Как проверить, что при нажатии кнопки вызывается правильный метод? Спасибо!
sampleComponent.jsx:
import * as React from 'react';
const SampleComponent = () => {
const sampleMethod = () => {
console.log('hello world');
};
return <button onClick={sampleMethod} type="button">Click Me</button>;
};
export default SampleComponent;
sampleComponent.test.jsx:
import * as React from 'react';
import { shallow } from 'enzyme';
import SampleComponent from './sample';
test('testing spy', () => {
const spy = jest.spyOn(SampleComponent.prototype, 'sampleMethod');
const wrapper = shallow(<SampleComponent />);
wrapper.find('button').simulate('click');
expect(spy).toHaveBeenCalled();
});
3 ответа
Ошибка означает, что функция sampleMethod
вы определили внутри функционального компонента SampleComponent
не определено в SampleComponent.prototype
. ТакSampleComponent.prototype.sampleMethod
является undefined
, шутка не может шпионить за undefined
значение.
Итак, правильный способ проверки sampleMethod
обработчик событий выглядит так:
index.spec.tsx
:
import React from 'react';
import SampleComponent from './';
import { shallow } from 'enzyme';
describe('SampleComponent', () => {
test('should handle click correctly', () => {
const logSpy = jest.spyOn(console, 'log');
const wrapper = shallow(<SampleComponent></SampleComponent>);
const button = wrapper.find('button');
expect(button.text()).toBe('Click Me');
button.simulate('click');
expect(logSpy).toBeCalledWith('hello world');
});
});
Мы можем шпионить за console.log
, утверждать это должно называться или нет.
Результат модульного тестирования со 100% покрытием:
PASS src/react-enzyme-examples/02-react-hooks/index.spec.tsx
SampleComponent
✓ should handle click correctly (19ms)
console.log node_modules/jest-mock/build/index.js:860
hello world
-----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.tsx | 100 | 100 | 100 | 100 | |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 5.036s
Версия зависимостей:
"react": "^16.11.0",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.15.1",
"jest": "^24.9.0",
"jest-environment-enzyme": "^7.1.1",
"jest-enzyme": "^7.1.1",
sample.js
import * as React from 'react';
export let sampleMethod;
const SampleComponent = () => {
sampleMethod = () => {
console.log('hello world');
};
return <button onClick={sampleMethod} type="button">Click Me</button>;
};
export default SampleComponent;
sample.test.js
import { shallow } from 'enzyme';
import SampleComponent, {sampleMethod} from './sample';
test('testing spy', () => {
const spy = jest.spyOn({'sampleMethod':sampleMethod}, 'sampleMethod');
const wrapper = shallow(<SampleComponent />);
wrapper.find('button').simulate('click');
expect(spy).toHaveBeenCalled(1);
});
Я знаю, что опаздываю с ответом, но думаю, что это поможет и другим разработчикам
Кроме того, в поисках способа шпионить за функцией внутри функционального компонента кажется, что это просто невозможно сделать никли (бу!). Я не хотел шпионить за журналом консоли, второе предложение с использованием объекта, определенного вне fc, я не смог заставить его работать.
Я придумал решение, которое тоже не красивое, но простое и может помочь другим с этой проблемой. Это НЕ слежка за функцией, о которой просили, но результат может быть достаточно близким для некоторых сценариев.
MyFC.tsx
const MyFC = ({callback}: {callback?:()=>void}) => {
const handleMyClick =
callback // this is the mock fn
|| ()=> console.log("do stuff") // this would be the regular implementation
return <button onClick={handleMyClick}>Click Me</button>
}
MyFC.test.tsx
it('should be triggered', () => {
const mockFn = jest.fn();
const wrapper = mount(<MyFC callback={mockFn}/>);
wrapper.find('button').simulate('click')
expect(mockFn).toBeCalled()
}
с таким подходом вы можете хотя бы проверить, вызывается ли он, с какими аргументами и т. д. Если кто-то найдет способ сделать это правильно, я был бы рад услышать...