How to use jest.spyOn with React function component using Typescript
我正在使用Typescript和钩子开发一个React应用程序,并且试图将Enzyme和Jest一起使用来测试功能组件。 我无法使用jest.spyOn来测试组件中的方法。 jest.spyOn方法无法正确解析,并在悬停时显示以下消息
"Argument of type '"validateBeforeSave"' is not assignable to
parameter of type '"context" |"setState" |"forceUpdate" |"render" |
"componentDidMount" |"shouldComponentUpdate" |"componentWillUnmount"
|"componentDidCatch" |"getSnapshotBeforeUpdate" | ... 6 more ... |
"UNSAFE_componentWillUpdate"'.ts(2345)"
我试图将实例转换为"任何"-
1 | const instance = wrapper.instance() as any; |
当然,这会在编译时忽略该问题,但是测试会抛出运行时错误,表明该功能在组件上不存在。
Cannot spy the validateBeforeSave property because it is not a
function; undefined given instead
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | // Some function Component const SomeComponent = (props: IMyComponentProps) => { const { classes } = props; // Component has state const [count, setCount] = useState(0); function validateBeforeSave(){ } function handleClick() { validateBeforeSave(); . . . } return ( <Button> className="saveBtn" onClick={handleClick} </Button> ); }; // Unit test describe('SomeComponent' () => { it('validates model on button click', () => { const wrapper = mount( <MuiThemeProvider theme={theme}> <SomeComponent/> </MuiThemeProvider>, ); const instance = wrapper.instance(); const spy = jest.spyOn(instance,"validateBeforeSave"); wrapper .find('.saveBtn') .at(0) .simulate('click'); expect(spy).toHaveBeenCalledTimes(1); }); } |
我在这里想念什么? spyOn如何与功能组件一起使用?
我使用create-react-app模板创建了应用程序,它具有测试包的这些依赖关系
1 2 3 4 5 6 7 8 9 | "devDependencies": { "ts-jest":"^23.10.3", "@types/jest":"24.0.9", "@types/enzyme":"^3.9.1", "@types/enzyme-adapter-react-16":"^1.0.2", "enzyme":"^3.9.0", "enzyme-adapter-react-16":"^1.11.2", "enzyme-to-json":"^3.3.5", } |
我也面临着同样的问题-我在下面确实喜欢-
1 2 3 4 5 6 7 8 9 10 11 | 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; |
测试-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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来断言它是否被调用
检查-https://stackoverflow.com/a/58637912/10734622
在此处再次发表我的评论以回答您的问题:
因此,您可以像下面这样修改函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // some validator function function validateBeforeSave(){ ... } // Some function Component const SomeComponent = (props: IMyComponentProps) => { const { classes, validateBeforeSave } = props; // Component has state const [count, setCount] = useState(0); function handleClick() { validateBeforeSave(); . . . } return ( <Button> className="saveBtn" onClick={handleClick} </Button> ); }; |
在单元测试中,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // Unit test describe('SomeComponent' () => { it('validates model on button click', () => { const validateSpy = jest.fn(); const wrapper = mount( <MuiThemeProvider theme={theme}> <SomeComponent validateSpy={validateSpy}/> </MuiThemeProvider>, ); const instance = wrapper.instance(); wrapper .find('.saveBtn') .at(0) .simulate('click'); expect(validateSpy).toHaveBeenCalledTimes(1); }); } |