我需要访问内部组件的状态,使其对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>
);
}
}
答案 0 :(得分:2)
首先,我认为你不应该在这里测试Button和Form功能。在此文件中,您应该只测试ContactForm
组件。
对于第一次失败,这应该有效:
find('Form')
(Form
应该有引号)
按钮相同:
find('Button');
通过这种方式,您甚至不必导入测试文件中的Form
和Button
组件;
然后,您不必为该按钮设置任何状态。您在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();"
});