我试图使用Enzyme和Jest来进行单元测试来模拟扩展React.Component
的类的函数,我发现可以模拟继承的setState
函数,但组件中没有其他功能。
例如,我的应用组件有TextInput
在setState
事件上调用onChangeText
,而TouchableOpacity
在{{submitFilter
调用onPress
1}}事件。
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = { filter: '' }
}
submitFilter = () => {
if (this.state.filter.length <= 0) {
Alert.alert('Filter is blank');
}
}
render() {
return (
<View style={styles.container}>
<View style={styles.filterContainer}>
<TextInput
style={styles.filterInput}
placeholder='Filter...'
value={this.state.filter}
onChangeText={(text) => {this.setState({ filter: text })}}
/>
<TouchableOpacity
style={styles.filterButton}
onPress={this.submitFilter}>
<Text style={styles.filterButtonLabel}>Go</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
使用相同的模式模拟setState
和submitFilter
,以及调用每个函数的相同模式:
import Adapter from 'enzyme-adapter-react-16';
import Enzyme from 'enzyme';
Enzyme.configure({ adapter: new Adapter() });
describe('interaction', () => {
let wrapper
let mockFn
beforeEach(() => {
wrapper = Enzyme.shallow(<App />)
mockFn = jest.fn()
})
describe('editing the filter input', () => {
beforeEach(() => {
wrapper.instance().setState = mockFn
wrapper.find('TextInput').first().props().onChangeText('waffles');
})
it('should update the filter state', () => {
expect(mockFn).toHaveBeenCalledTimes(1)
})
})
describe('clicking filter button', () => {
beforeEach(() => {
wrapper.instance().submitFilter = mockFn
wrapper.find('TouchableOpacity').first().props().onPress()
})
it('should invoke the submitFilter callback', () => {
expect(mockFn).toHaveBeenCalledTimes(1)
})
})
})
只有第一次通过,我不确定用什么方法来模拟submitFilter
函数来验证它是否被调用?
interaction
editing the filter input
✓ should update the filter state (3ms)
clicking filter button
✕ should invoke the submitFilter callback (18ms)
● interaction › clicking filter button › should invoke the submitFilter callback
expect(jest.fn()).toHaveBeenCalledTimes(1)
Expected mock function to have been called one time, but it was called zero times.
at Object.<anonymous> (App.test.js:47:16)
at tryCallTwo (node_modules/promise/lib/core.js:45:5)
at doResolve (node_modules/promise/lib/core.js:200:13)
at new Promise (node_modules/promise/lib/core.js:66:3)
at tryCallOne (node_modules/promise/lib/core.js:37:12)
at node_modules/promise/lib/core.js:123:15
有什么想法吗?
答案 0 :(得分:0)
在我升级到需要适配器的Enzyme 3之后,我也遇到了这个问题。我修复它的方法是在StackOverflow上查看this answer。
根据migration guide,您收到的实例()实际上是对底层反应元素的转换。所以你没有得到实际的模拟方法。要解决这个问题,你需要监视原型。
import Adapter from 'enzyme-adapter-react-16';
import Enzyme from 'enzyme';
Enzyme.configure({ adapter: new Adapter() });
describe('interaction', () => {
let wrapper
let mockFn
let spy
describe('editing the filter input', () => {
beforeEach(() => {
spy = jest.spyOn(App.prototype, 'setState');
wrapper = Enzyme.shallow(<App />);
wrapper.find('TextInput').first().props().onChangeText('waffles');
})
afterEach(() => {
spy.mockRestore();
})
it('should update the filter state', () => {
expect(spy).toHaveBeenCalledTimes(1);
})
})
describe('clicking filter button', () => {
beforeEach(() => {
spy = jest.spyOn(App.prototype, 'submitFilter');
wrapper = Enzyme.shallow(<App />);
wrapper.find('TouchableOpacity').first().props().onPress()
})
afterEach(() => {
spy.mockRestore();
})
it('should invoke the submitFilter callback', () => {
expect(spy).toHaveBeenCalledTimes(1)
})
})
})