【问题标题】:Enzyme- How to set state of inner component?酶 - 如何设置内部组件的状态?
【发布时间】:2018-05-07 20:32:52
【问题描述】:

我需要访问内部组件的状态,使其激活点击事件,我的问题是使用mount时Enzyme不允许这样做,这只能通过shallow渲染酶来实现,如上所述在here 上,也如前所述,我尝试使用dive 获取Form 组件,然后再次从Form 获取我需要到达的Button 组件,问题是我的测试用例不断失败,因为Form 组件长度为零。

酶:3.1.0

enzyme-adapter-react-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>
    );
  }
 }

【问题讨论】:

  • 为了最大化获得帮助的机会,我建议将代码减少到问题的核心并提供测试代码。

标签: reactjs jestjs enzyme


【解决方案1】:

首先,我认为您不应该在这里测试 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();"
});

【讨论】:

  • 感谢您的回答,通过一些调整确实对我有用。
猜你喜欢
  • 2016-06-09
  • 2021-06-29
  • 2020-10-11
  • 2018-09-19
  • 2021-02-16
  • 2016-09-27
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
相关资源
最近更新 更多