我正在使用Typescript和钩子开发React应用程序,并且我试图将Enzyme与Jest一起使用以测试功能组件。我无法使用jest.spyOn来测试组件中的方法。 jest.spyOn方法无法正确解析,并在悬停时显示以下消息
“类型'“ validateBeforeSave”的参数不能分配给 '“ context”类型的参数| “ setState” | “ forceUpdate” | “渲染” | “ componentDidMount” | “ shouldComponentUpdate” | “ componentWillUnmount” | “ componentDidCatch” | “ getSnapshotBeforeUpdate” | ... 6更多... | “ UNSAFE_componentWillUpdate”'。ts(2345)“
我试图将实例强制转换为'Any'-
const instance = wrapper.instance() as any;
这当然会在编译时忽略该问题,但是测试会抛出运行时错误,提示该功能在组件上不存在。
无法监视validateBeforeSave属性,因为它不是 功能;未给定
// Some function Component
const SomeComponent = (props: IMyComponentProps) => {
const { classes } = props;
// Component has state
const [count, setCount] = useState(0);
function validateBeforeSave(){
}
function handleClick() {
validateBeforeSave();
.
.
.
}
return (
<div>
<Button>
className="saveBtn"
onClick={handleClick}
</Button>
</div>
);
};
// 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模板创建了应用程序,它具有测试包的这些依赖项
"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",
}
答案 0 :(得分:1)
我也面临着同样的问题-我确实喜欢以下内容-
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;
测试-
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上进行间谍,以断言它是否被调用
答案 1 :(得分:0)
再次在此处发表我的评论以回答您的问题:validateBeforeSave
函数在SomeComponent
中声明,从而使其成为无法在外部访问的封闭/私有范围函数。您可以将该函数作为道具传递,然后可以创建间谍并将其作为道具值传递给您的测试,并测试是否通过了调用(间谍)的道具函数
所以您可以像下面这样修改函数:
// 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 (
<div>
<Button>
className="saveBtn"
onClick={handleClick}
</Button>
</div>
);
};
在单元测试中,如下所示:
// 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);
});
}
答案 2 :(得分:0)
我在用 React 16.x.x 模拟回调 prop 方法时遇到了类似的问题,酶实例方法返回 null,你可以做的是直接将 jest.fn() 作为 prop 传递。
示例:
it('should invoke callback with proper data upon checkbox click', () => {
const spyCheckboxClick = jest.fn((id, item) => ({
id,
item,
}))
const component: any = enzyme.mount(
<SectionColumn {...{
...mockProps,
onCheckboxClick: spyCheckboxClick,
}} />
);
expect(spyCheckboxClick).toHaveBeenCalledTimes(0);
// perform click to checkbox
const checkboxComponent = component.find('StyledCheckbox');
const input = checkboxComponent.first().children();
input.simulate('change');
expect(spyCheckboxClick).toHaveBeenCalledTimes(1);
expect(spyCheckboxClick()).toEqual(null)
});