我的表格如下:
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>
);
}
});
以下是我为此编写单元测试的方法:
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:'[email protected]', 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: '[email protected]' } });
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
字段的模拟返回此错误:
Method “props” is only meant to be run on a single node. 0 found instead.
所以我不得不评论他们。但是我会得到这个错误:
expect(jest.fn()).toBeCalledWith(expected)
Expected mock function to have been called with:
[{cp:true, message: 'testmessage', name:'testname', affiliation:'testaaa', email:'[email protected]', address:'test address', city:'testcity', country:'testcountry', zipcode:'12345', phone: '0987654321'}]
But it was not called.
我假设server
是你导入反应组件文件的一些外部模块,如下所示:
import server from 'server'
然后你需要像你这样在你的测试文件中模拟它
import server from '../src/data/server'
jest.mock('../src/data/server', ()=> ({server: {report: jest.fn()}}))
在你的测试中,你可以期待thar server.report
被称为:
expect(server.report.mock).toBeCalledWith(data);
并且只找到一个元素使用closest
而不是find
,因为后者总是返回一个元素数组,你不能使用prop
。如果你使用find你需要这样做component.find.first('button')
,这将与component.closest('button')
相同