[英]React unit tests not failing when test suite is ran
我為React組件創建了一個單元測試。 如果沒有提供電子郵件地址,則第一個測試應該通過,並且我們提醒用戶沒有提供。 這作為單獨的測試以及整個套件運行都通過。 如果提供了電子郵件但沒有提供密碼,則第二項測試應該通過,並通過消息提示用戶需要提供密碼來警告用戶。
我看到的問題是,如果我告訴密碼單元測試來檢查警報是否未提供電子郵件。 在這種情況下,如果我單獨運行測試,它將失敗,表示需要按預期提供電子郵件。 但是,如果我將它作為套件運行,並且首先運行了電子郵件檢查,則密碼檢查單獨運行了,如果不應該提供密碼,則密碼檢查通過,因為提供了電子郵件地址並且警報消息應該沒有密碼。 如果我先使用密碼檢查來運行測試套件,然后將電子郵件檢查與電子郵件檢查分開,則密碼檢查會按我的預期失敗。 根據運行測試的順序,我會得到不同的結果。
我試過通過命令行運行package --env = jsdom --watchAll = false --coverage選項,使用package.json中的npm配置,並使用webstorm運行配置,但是它們都產生相同的結果。
單元測試:
import React from 'react';
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16.3';
import SignInForm from '../components/SignInForm';
//import { mount, shallow, render } from 'enzyme';
configure({ adapter: new Adapter() });
test('Errors when no email is input', () => {
jest.spyOn(window, 'alert').mockImplementation(() => {});
const wrapper = shallow(<SignInForm />);
wrapper.find('input#email_address').simulate('change', {target: { value: '' }});
wrapper.find('button').simulate('click');
expect(window.alert).toHaveBeenCalledWith('Email address is required to sign in');
});
test('Errors when no password is input', () => {
jest.spyOn(window, 'alert').mockImplementation(() => {});
const wrapper = shallow(<SignInForm />);
wrapper.find('input#email_address').simulate('change', {target: { value: "Tst@test.com" }});
wrapper.find('button').simulate('click');
expect(window.alert).toHaveBeenCalledWith('Email address is required to sign in');
});
登錄表單Web組件:
import React, {Component} from 'react';
export default class SignInForm extends Component {
constructor(props) {
super(props);
this.state = {email_address: '', password: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(field, event) {
this.setState({[field]: event.target.value});
}
handleSubmit(event) {
if (event) {
event.preventDefault();
}
const {email_address, password} = this.state;
if (email_address === '') {
alert("Email address is required to sign in");
return;
} else if (password === '') {
alert("Password is required to sign in");
return;
}
}
render() {
return (
<form id="signInForm">
<div className="form-group">
<label htmlFor="email_address">Email address</label>
<input type="email" className="form-control" name="email_address" id="email_address"
aria-describedby="emailHelp" placeholder="Enter email" onChange={this.handleChange.bind(null, 'email_address')} />
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input type="password" className="form-control" id="password" name="password" placeholder="Password" onChange={this.handleChange.bind(null, 'password')} />
</div>
<button type="submit" className="btn btn-primary" onClick={this.handleSubmit.bind(this)}>Submit</button>
</form >
);
}
}
這是因為開玩笑在內部跟蹤正在發生的一切。 如果它運行一次(從您的第一個測試開始),它將“記住”第二個測試運行的時間。 我敢打賭,如果您更改這兩個測試的順序,它們將通過。 但這不是真正的解決方案。
在運行每個測試之前,您必須jest.clearAllMocks()
。 您應該將所有測試划分為一個describe
塊,並在其中運行beforeEach
,以便可以在每次測試之前自動運行jest.clearAllMocks()
。
describe('unit tests', () => ({
beforeEach(() => {
jest.clearAllMocks()
})
// test('Errors when no email is input', () => { unit tests here
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.