我想用Jest/Enzyme
编写登录页面的单元测试(使用React
),我试图模拟服务器响应,因此我可以进行测试登录表单是否正常工作。
我有一个像这样的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
响应。
我尝试了多种方法,例如使用spyOn
,mockImplementation
等,但都没有成功。这些是我的一些尝试:
// ------------------ (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 () => { ... });
答案 0 :(得分:1)
尝试
const handleClick = jest.spyOn(LoginPage.prototype, 'handleClick).
mockImplementation(() => {
//your mock
}
和
expect(handleClick).toHaveBeenCalled();
请记住,jest.spyOn
仅适用于普通功能,不适用于箭头功能。另外,在安装测试组件之前,您应该设置间谍。