我目前正在为我的React + MaterialUi应用程序编写单元测试。
在我的应用程序中,我有一个Dialog。我想确保取决于按下对话框上的按钮:
<FlatButton
label="Cancel"
secondary={true}
onTouchTap={this._cancelDialog.bind(this)}
/>
<FlatButton
label="Submit"
primary={true}
onTouchTap={this._confirmDialog.bind(this)}
/>
内部状态相应变化。
不幸的是我无法使用对话框内容
TestUtils.scryRenderedComponentsWithType(FlatButton)
或
scryRenderedComponentsWithTag("button")
等等。
有关如何测试该流程的任何想法?
更新1
所以我可以通过调用TestUtils.scryRenderedComponentsWithType(Dialog)来获取Dialog实例。但我无法得到对话框的内容。 DOM明智的内容不会在视图内部呈现。它在文档级别(div)上的新创建节点中呈现。所以我试过这个:
let cancelButton = window.document.getElementsByTagName("button")[0];
Simulate.click(cancelButton);
上面的例子中的cancelButton是正确的DOM元素。但是,Simulate.click不会触发组件单击功能。
问候 纳斯
答案 0 :(得分:5)
刚遇到同样的问题。我查看了源代码,Dialog组件的render方法实际上创建了组件RenderToLayer
的实例。此组件表现为门户网站,并通过在其“渲染函数”中返回null并将其直接附加到正文来中断反应的DOM树。
幸运的是,RenderToLayer
组件接受了prop render
,它实质上允许组件将一个函数传递给门户,当它处于渲染周期时。这意味着我们实际上可以自己手动触发此事件。我承认,这并不完美,但经过几天的努力寻找解决方案后,我正在试着写下我的测试:
var component = TestUtils.renderIntoDocument(<UserInteractions.signupDialog show={true}/>)
var dialog = TestUtils.renderIntoDocument(component.refs.dialog.renderLayer())
var node = React.findDOMNode(dialog)
这是我的UserInteractions.signupDialog的样子:
exports.signupDialog = React.createClass({
...
render: function() {
var self = this;
return (
<div>
<Dialog
ref='dialog'
title="Signup"
modal={false}
actions={[
<Button
label="Cancel"
secondary={true}
onTouchTap={self.__handleClose}
/>,
<Button
label="Submit"
primary={true}
keyboardFocused={true}
onTouchTap={self.__handleClose}
/>
]}
open={self.props.show}
onRequestClose={self.__handleClose}
>
<div className='tester'>ham</div>
<TextField id='tmp-email-input' hintText='email' type='text'/>
</Dialog>
</div>
)
}
})
现在我可以对对话框中呈现的子组件进行断言,甚至可以对绑定到原始组件的事件进行断言,因为它们的关系得以维持。
如果您要继续使用材料ui,我绝对建议您在测试堆栈中设置调试器。对这样的事情没有太大的帮助。这是我的调试脚本的样子:
// package.json
{
...
"scripts": {
"test": "mocha --compilers .:./test/utils/compiler.js test/**/*.spec.js",
"debug": "mocha debug --compilers .:./test/utils/compiler.js test/**/*.spec.js"
}
}
现在您可以使用npm test
运行mocha测试,并使用npm run debug
进入调试器。一旦进入调试器,它将立即暂停并等待您输入断点。此时,输入c
继续。现在,您可以在代码中的任何位置放置debugger;
语句,以生成调试器将响应的断点。找到断点后,它会暂停并允许您使用本地范围使用代码。此时,输入repl
以输入代码的本地范围并访问您当地的变种。
也许您不需要调试器,但也许其他人会觉得这很有帮助。祝你好运,编码愉快!
答案 1 :(得分:4)
解决方法如下:
/*
* I want to verify that when i click on cancel button my showModal state is set * to false
*/
//shallow render my component having Dialog
const wrapper= shallow(<MyComponent store={store} />).dive();
//Set showModal state to true
wrapper.setState({showModal:true});
//find out cancel button with id 'cancelBtn' object from actions and call onTouchTap to mimic button click
wrapper.find('Dialog').props().actions.find((elem)=>(elem.props.id=='cancelBtn')).props.onTouchTap();
//verify that the showModal state is set to false
expect(wrapper.state('showModal')).toBe(false);
答案 2 :(得分:0)
我遇到了同样的问题并解决了这个问题:
const myMock = jest.genMockFunction();
const matcherComponent = TestUtils.renderIntoDocument(
<MatcherComponent onClickCancel={myMock} activAction/>
);
const raisedButton = TestUtils.findRenderedComponentWithType(
matcherComponent, RaisedButton);
TestUtils.Simulate.click(ReactDOM.findDOMNode(raisedButton).firstChild);
expect(myMock).toBeCalled();
对我来说很好。但是,我仍在努力使用Simulate.change
答案 3 :(得分:0)
Solution by avocadojesus很棒。但我有一个补充。如果您尝试应用此解决方案并收到错误:
错误:'警告:上下文类型失败:标记了上下文
muiTheme
根据{{1}}的要求,但其值为DialogInline
。
你应该修改他的代码如下:
undefined
答案 4 :(得分:0)
材料UI分叉这2种酶方法。您需要将createMount
或createShallow
与潜水选项https://material-ui.com/guides/testing/#createmount-options-mount一起使用