用笑话和酶法窥探React功能组分法;无法对基元值执行spyOn



我正在尝试测试React组件,并确保在单击其按钮时,调用正确的方法。然而,当我试图运行我的测试并试图监视该方法时,我得到了以下消息:

错误:无法对基元值执行spyOn;未定义的给定

如何测试单击按钮时是否调用了正确的方法?谢谢

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();
});

错误意味着,您在功能组件SampleComponent中定义的函数sampleMethod未在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 util = {sampleMethod: null };
const SampleComponent = () => {
util.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, {util} from './sample';
test('testing spy', () => {
const spy = jest.spyOn( util, 'sampleMethod' );
const wrapper = shallow(<SampleComponent />);
wrapper.find('button').simulate('click');
expect(spy).toHaveBeenCalled(1);
});

我知道我来不及回答,但我认为这将有助于其他一些开发人员也

此外,在寻找监视功能组件内部函数的方法时,似乎不可能做到nicley(booo!(。我不想窥探控制台日志,第二个建议是使用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.tsx

it('should be triggered', () => {
const mockFn = jest.fn();
const wrapper = mount(<MyFC callback={mockFn}/>);
wrapper.find('button').simulate('click')
expect(mockFn).toBeCalled()        
}

使用这种方法,您至少可以测试它是否被调用,使用什么参数等如果有人能找到一种正确的方法,我会很高兴听到。。。

最新更新