React Jest/Enzyme:模拟/覆盖ES6类方法的响应



我想为用React编写的登录页面编写一个单元测试(使用Jest/Enzyme(,我试图模拟服务器响应,这样我就可以测试登录表单是否正常工作。

我有一个React类组件,如下所示:

// LoginPage.js
export class LoginPage extends Component {
// ...
handleClick = async () => {

const username = this.state.username;
const password = this.state.password;
const result = await callServer(username, password); // "fetch" used here
console.log('Server Response:', result);
if (result) // redirect
};
render() {
return (
<Wrapper> // Styled Components

<Input type="text" id="loginUsername" ... />
<Input type="password" id="loginPassword" ... />
<Button onClick={this.handleClick}>
Submit
</Button>
</Wrapper>
)
}
}
export default withRouter(MyClass);

我的测试文件:

// LoginPage-test.js
import React from 'react';
import {configure, shallow} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
import {LoginPage} from './LoginPage';
import Input from './Input';
import Button from './Button';
it('test the login page', async () => {
const wrapper = shallow(<LoginPage/>),
inputUsername = wrapper.find(Input).findWhere(n => n.prop('id') === 'loginUsername'),
inputPassword = wrapper.find(Input).findWhere(n => n.prop('id') === 'loginPassword'),
loginButton = wrapper.find(Button).findWhere(n => n.prop('children') === 'Submit');
inputUsername.simulate('change', { target: { name: 'loginUsername', value: 'test_user' } });
inputPassword.simulate('change', { target: { name: 'loginPassword', value: 'test_pass' } });
const result = await loginButton.props().onClick();
wrapper.update();
});

通过这个测试,我可以看到服务器响应(console.log(和通过的测试。但我不想调用真正的服务器(因为这在测试中不是一个好的做法(,相反,我想模拟handleClick响应。

我尝试了很多方法,spyOnmockImplementation等等都没有成功。以下是我的一些尝试:

// ------------------ (1) ---------------------
jest.doMock('./LoginPage', () => {
return jest.fn().mockImplementation(() => {
return {
__esModule: true,
...(jest.requireActual(LoginPage)),
LoginPage: {
handleClick: async () => {
console.log('MOCK_TEST');
return new Promise.resolve('MOCK_TEST');
}
}
};
});
});
it('test the login page', async () => { ... });
// ------------------ (2) ---------------------
it('test the login page', async () => {

// ...
inputUsername.simulate('change', { target: { name: 'loginUsername', value: 'test_user' } });
jest.spyOn(wrapper.instance(), 'handleClick').mockImplementation(() => {
console.log('MOCK_TEST');
return 'MOCK_TEST';
});
wrapper.update();
// ...
});
// ------------------ (3) ---------------------
jest.mock(LoginPage, jest.fn());
LoginPage.mockImplementation(
() => ({
handleClick: () => {
console.log('MOCK_TEST');
return 'MOCK_TEST';
}
})
)
it('test the login page', async () => { ... });

尝试

const handleClick = jest.spyOn(LoginPage.prototype, 'handleClick).
mockImplementation(() => {
//your mock
}

expect(handleClick).toHaveBeenCalled();

请记住,jest.spyOn仅适用于正常函数,而不适用于箭头函数。此外,您应该在安装测试组件之前设置spy。

最新更新