我的代码的简化设置如下:
App.js
class App extends React.Component {
componentDidMount() {
const { thirdPartyAPI } = this.props;
thirdPartyAPI.field.onValueChanged(this.handleValueChange);
}
handleValueChange = (value) => {
// callback to do complex validation stuff and suchlike
// update state
}
render() {
// display stuff
}
}
App.test.js
each([...]).
.test('App is rendered according to...',
async (...) => {
const mockApi = {
field: {
onValueChanged: ????
}
}
const AppComponent = await shallow(
<App thirdPartyAPI={mockApi} />,
);
});
OnValueChanged检测用户何时更改了react-app之外的值。从用户的角度来看,这是可行的,但是开玩笑的测试给我带来了麻烦。
简单地说:我该如何测试?
我需要模拟API函数,但是我需要使用App.js中定义的回调函数handleValueChange。我已经忘记了我所阅读和观看的开玩笑教程,其中很多非常详细,但是似乎没有一个适用于这种特殊情况。
是否有可能测试此代码?如果是这样,怎么办?如果没有,我应该如何重组我的代码,以便我可以测试它?
如果有人可以指出正确的方向,我将不胜感激。
答案 0 :(得分:1)
如果您以thirdPartyAPI.field.onValueChanged
的形式将模拟函数传递给组件,则它将以this.handleValueChange
进行调用。
模拟功能会记录调用它们的所有内容,因此您可以使用模拟功能通过mockFn.mock.calls
获取this.handleValueChange
。
在测试中检索到this.handleValueChange
后,您可以直接调用它并验证它是否按预期工作。
这是一个简单的工作示例:
import * as React from 'react';
import { shallow } from 'enzyme';
class App extends React.Component {
constructor(...args) {
super(...args);
this.state = { val: 'original' };
}
componentDidMount() {
const { thirdPartyAPI } = this.props;
thirdPartyAPI.field.onValueChanged(this.handleValueChange);
}
handleValueChange = (value) => {
this.setState({ val: value });
}
render() { return null; }
}
test('App', () => {
const onValueChangedMock = jest.fn();
const thirdPartyAPIMock = { field: { onValueChanged: onValueChangedMock } };
const wrapper = shallow(<App thirdPartyAPI={thirdPartyAPIMock} />);
expect(wrapper.state('val')).toBe('original'); // Success!
const handleValueChange = onValueChangedMock.mock.calls[0][0]; // <= get handleValueChange...
handleValueChange('updated'); // <= ...now call it directly
expect(wrapper.state('val')).toBe('updated'); // Success!
})