在Jest中为React表单编写单元测试 [英] Write a Unit test in Jest for a React form
问题描述
我的表格如下:
import React from 'react/lib/ReactWithAddons';
import { server } from '../data/server';
export const Report = React.createClass({
mixins: [React.addons.LinkedStateMixin],
sendReport(event) {
event.preventDefault();
var data = {
ac: this.ab.checked,
cp: this.cp.checked,
nr: this.nr.checked,
il: this.il.checked,
message: this.message.value,
name: this.name.value,
affiliation: this.affiliation.value,
email: this.email.value,
address: this.address.value,
city: this.city.value,
country: this.country.value,
zipcode: this.zipcode.value,
phone: this.phone.value,
};
server.report(this.props.params.id, data,() => { ..... });
},
render: function() {
return (
<form onSubmit={this.sendReport}>
<div><input id='reason' ref={(ref) => this.ab = ref} name='reason' type='radio' value='ab' required /></div>
<div><input id='reason' ref={(ref) => this.cp = ref} name='reason' type='radio' value='cp' /></div>
<div><input id='reason' ref={(ref) => this.nr = ref} name='reason' type='radio' value='nr' /></div>
<div><input id='reason' ref={(ref) => this.il = ref} name='reason' type='radio' value='il' /></div>
<div><textarea ref={(ref) => this.message = ref} name='message' className="form-control" type='textarea' rows="4" cols="50" required/></div>
<div><input id='name' ref={(ref) => this.name = ref} name='name' className="form-control" type='text' required /></div>
<div><input id='affiliation' ref={(ref) => this.affiliation = ref} name='affiliation' className="form-control" type='text' required /></div>
<div><input id='email' ref={(ref) => this.email = ref} name='email' className="form-control" type='email' required /></div>
<div><input id='address' ref={(ref) => this.address = ref} name='address' className="form-control" type='text' required /></div>
<div><input id='city' ref={(ref) => this.city = ref} name='city' className="form-control" type='text' required /></div>
<div><select id='country' ref={(ref) => this.country = ref} name='country' className="form-control" defaultValue="" required >
<option value="">Choose country</option>
<option value="Canada" >Canada</option>
....
</select></div>
<div><input id='zipcode' ref={(ref) => this.zipcode = ref} name='zipcode' className="form-control" type='text' required /></div>
<div><input id='phone' ref={(ref) => this.phone = ref} name="phone" type='text' pattern="[0-9]*" className="form-control" title= "Numbers Only" required /></div>
<div><button id='send' type="submit" >Send</button></div>
</form>
);
}
});
这是我尝试为其编写单元测试的方式:
Here is how I'm trying to write a unit test for it:
import { Report } from '../src/components/report';
import { server } from '../src/data/server';
import { shallow } from 'enzyme';
import React from 'react/lib/ReactWithAddons';
import { shallowToJson } from 'enzyme-to-json';
import ReactTestUtils from 'react-addons-test-utils';
describe('Report form', () => {
const component = shallow(<Report params={{ id: '1033083fe' }} />);
const sendReport = jest.fn();
it('sends the form correctrly', ()=> {
var data = {cp:true, message: 'testmessage', name:'testname', affiliation:'testaaa', email:'sss@test.com', address:'test address', city:'testcity', country:'testcountry', zipcode:'12345', phone: '0987654321'}
const button = component.find('button');
const cp = component.find('#cp');
const message = component.find('#message');
const name = component.find('#name');
const affiliation = component.find('#affiliation');
const email = component.find('#email');
const address = component.find('#address');
const city = component.find('#city');
const country = component.find('#country');
const zipcode = component.find('#zipcode');
const phone = component.find('#phone');
component.setState({ phone: '0987654321' });
expect(component.find('#phone').length).toEqual(1);
## cp.simulate('change', { target: { value: true } });
## message.simulate('change', { target: { value: 'testmessage' } });
name.simulate('change', { target: { value: 'testname' } });
affiliation.simulate('change', { target: { value: 'testaaa' } });
email.simulate('change', { target: { value: 'sss@test.com' } });
address.simulate('change', { target: { value: 'test address' } });
city.simulate('change', { target: { value: 'testcity' } });
country.simulate('change', { target: { value: 'testcountry' } });
zipcode.simulate('change', { target: { value: '12345' } });
phone.simulate('change', { target: { value: '0987654321' } });
button.simulate('click');
expect(sendReport).toBeCalledWith(data);
expect(shallowToJson(component)).toMatchSnapshot();
});
});
目标是检查表单是否将数据正确发送到sendreport()
方法(单击send
按钮之后).所有字段均为必填项.模拟"cp"和message
字段将返回此错误:
The goal is to check if the form sends the data correctly to the sendreport()
method or not (after clicking the send
button). All the fields are mandatory. The simulation of 'cp' and message
fields returns this error:
Method "props" is only meant to be run on a single node. 0 found instead.
所以我不得不评论他们.但是然后我会得到这个错误:
So I had to comment them. But then I'll get this error:
expect(jest.fn()).toBeCalledWith(expected)
Expected mock function to have been called with:
[{cp:true, message: 'testmessage', name:'testname', affiliation:'testaaa', email:'sss@test.com', address:'test address', city:'testcity', country:'testcountry', zipcode:'12345', phone: '0987654321'}]
But it was not called.
推荐答案
我假定server
是您导入到反应组件文件中的某个外部模块,如下所示:
I assume that server
is some external module that you import into your react component file like this:
import server from 'server'
然后您需要像这样在测试文件中对其进行模拟
Then you need to mock it in your test file like like this
import server from '../src/data/server'
jest.mock('../src/data/server', ()=> ({server: {report: jest.fn()}}))
在您的测试中,您可以期望server.report
被称为:
In your test you can then expect thar server.report
was called:
expect(server.report.mock).toBeCalledWith(data);
要查找仅一个元素,请使用closest
而不是find
,因为后者总是返回不能使用prop
的元素数组.如果使用find,则需要像component.find.first('button')
这样执行,这与component.closest('button')
And to find only one element use closest
instead of find
as the later always returns an array of elements where you cant use prop
on. If you use find you need to do it like this component.find.first('button')
, this would be the same as component.closest('button')
这篇关于在Jest中为React表单编写单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!