簡體   English   中英

運行測試套件時,React單元測試不會失敗

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM