酶 - 如何设置内部组件的状态?

时间:2017-11-23 20:30:46

标签: reactjs jestjs enzyme

我需要访问内部组件的状态,使其对click事件有效,我的问题是Enzyme在使用mount时不允许这样做,这只能通过shallow渲染来实现在here上提到的酶,也提到我已经尝试使用dive来获取Form组件,并再次从Form获取我需要访问的Button组件,问题是我的测试用例因为表单组件长度为零而继续失败。

酶:3.1.0

酶 - 适配 - 反应-15:1.0.1“

我对Enzyme很新,任何帮助都将不胜感激,谢谢

contactus.test.js

 test('It should simulate submit action ', ()=>{
   let contactUs = shallow(<ContactUs />);
   sinon.spy(ContactUs.prototype, 'submitMessage');// Verify this method call
   let form = contactUs.find(Form)
   expect(form.length).toBe(1);//Failing over here
   let button = form.dive().find(Button);
   expect(button.length).toBe(1);
   button.setState({disabled : false});//Need to achieve this 
   expect(button).toBeDefined();
   expect(button.length).toBe(1);
   expect(button.props().label).toBe('SEND MESSAGE');

   button.find('a').get(0).simulate('click');
  expect(ContactUs.prototype.submitMessage).toHaveProperty('callCount', 
 1);
});

contactus.js

import React, {Component,PropTypes} from 'react';
import Form from './form';
import {sendSubscriptionMessage} from '../../network';
import Button from '../Fields/Button';

export default class ContactUs extends Component {

constructor(props) {
    super(props);
    this.state = {
        contactData: {}
    }
}

onChangeHandler(event) {
    let value = event.target.value;
    this.state.contactData[event.target.name] = value;
}

submitMessage(event) {
    event.preventDefault();
    sendSubscriptionMessage(this.state.contactData);
}

render() {
    return (<div className = "row pattern-black contact logo-container" id = "contact">
        <div className = "container" >
        <h2 className = "sectionTitle f-damion c-white mTop100" >
        Get in Touch!

       <Form onChangeHandler = {
            this.onChangeHandler.bind(this)
        } >
        <Button onClick = {
            this.submitMessage.bind(this)
        }
        className = "gradientButton pink inverse mTop50"
        label = "SEND MESSAGE" / >
        </Form> </div> 
        </div>
    );
  }
 }

1 个答案:

答案 0 :(得分:2)

首先,我认为你不应该在这里测试Button和Form功能。在此文件中,您应该只测试ContactForm组件。

对于第一次失败,这应该有效:

find('Form')Form应该有引号)

按钮相同: find('Button');

通过这种方式,您甚至不必导入测试文件中的FormButton组件;

然后,您不必为该按钮设置任何状态。您在Button.test.js文件中测试按钮功能。 你在这里要做的就是调用它的方法: button.nodes[0].props.onClick();

总的来说,这就是你的测试应该是这样的(注意我没有测试它,我一直在使用Jest测试我的组件,但逻辑应该是相同的):

 test('It should simulate submit action ', ()=>{
   const wrapper = shallow(<ContactUs />);
   const spy = sinon.spy(ContactUs.prototype, 'submitMessage'); // Save the spy into a new variable

   const form = wrapper.find('Form') // I don't know if is the same, but in jest is enough to pass the component name as a string, so you don't have to import it in your test file anymore.

   expect(form).to.have.length(1);

   const button = wrapper.find('Button'); // from what I see in your code, the Button is part of the ContactUs component, not of the Form.

   expect(button).to.have.length(1);

   /* These lines should not be part of this test file. Create a test file only for the Button component.
   button.setState({disabled : false}); 
   expect(button).toBeDefined();
   expect(button.length).toBe(1);
   expect(button.props().label).toBe('SEND MESSAGE');
   */

   button.nodes[0].props.onClick(); // Here you call its method directly, cause we don't care about its internal functionality; we want to check if the "submitMessage" method has been called.


  assert(spy.called); // Here I'm not very sure... I'm a Jest fan and i would have done it like this "expect(spy).toHaveBeenCalled();"
});