在Jest中为React表单编写单元测试 [英] Write a Unit test in Jest for a React form

查看:199
本文介绍了在Jest中为React表单编写单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的表格如下:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆