【问题标题】:Write a Unit test in Jest for a React form在 Jest 中为 React 表单编写单元测试
【发布时间】:2017-04-06 16:06:18
【问题描述】:

我的表格如下:

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:'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字段的模拟返回这个错误:

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:'sss@test.com', address:'test address', city:'testcity', country:'testcountry', zipcode:'12345', phone: '0987654321'}]
But it was not called.

【问题讨论】:

    标签: unit-testing reactjs jestjs enzyme


    【解决方案1】:

    我假设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') 相同

    【讨论】:

    • 找不到server!! :-O 返回此错误:Cannot find module 'server' from 'report-test.jsx'
    • 正如我所说,“我假设您导入服务器”。从您的代码中不清楚server 的来源。请更新您的问题以显示服务器的来源。
    • 你是对的。我正在从正确的路径导入 server 模块。两个测试都看不懂! :/ server 所做的就是从表单中获取这些数据并触发相关的rest api thingi。
    • 请注意,路径必须与测试文件相关。
    • 当你使用import { server } 时,mock需要改为jest.mock('../src/data/server', ()=&gt; ({server: {report: jest.fn()}}))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多