unit-testing - 使用 Material UI Dialog 对 React 组件进行单元测试

标签 unit-testing reactjs material-ui reactjs-testutils

我目前正在为我的 React + MaterialUi 应用程序编写单元测试。

在我的应用程序中,我有一个对话框。我想确定取决于对话框上按下的按钮:

<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 明智的内容不会呈现在 View 本身内。它呈现在文档级别(div)上的新创建节点中。所以我尝试了这个:
let cancelButton = window.document.getElementsByTagName("button")[0];
Simulate.click(cancelButton);

上例中的 cancelButton 是正确的 DOM 元素。 Simulate.click 但是不会触发组件单击功能。

问候
乔纳斯

最佳答案

刚刚遇到了同样的问题。我查看了源代码,Dialog组件的render方法实际上创建了组件的实例RenderToLayer .这个组件的行为就像一个门户,并通过在其渲染函数中返回 null 并直接附加到主体来破坏 react 的 DOM 树。

幸运的是,RenderToLayer组件接受 Prop render ,它本质上允许组件向门户传递一个函数,以便在它处于渲染周期时调用。这意味着我们实际上可以自己手动触发这个事件。我承认,这并不完美,但是经过几天的尝试,试图为这个 hack 找到解决方案后,我认输并像这样编写我的测试:

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>
    )
  }
})

现在我可以对对话框中呈现的子组件进行断言,甚至可以对绑定(bind)到我的原始组件的事件进行断言,因为它们的关系得到了维护。

如果您要继续使用 Material 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输入您的代码的本地范围并访问您的本地变量。

也许您不需要调试器,但也许其他人会发现这很有帮助。祝你好运,编码愉快!

关于unit-testing - 使用 Material UI Dialog 对 React 组件进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34312668/

相关文章:

unit-testing - Grails 2单元测试中的元类删除域方法

javascript - 通过扩展运算符中的变量传递对象属性

reactjs - 如何通过material-ui本地使用material字体和图标?

javascript - 在 Formik 和 Material-UI 中存储未屏蔽的 InputMask 值

c# - 如何在单元测试中测试两个对象是否相等?

java - 以编程方式加载数据库设置并与 DBUnit 中的预期数据库进行比较

.net - 多线程应用程序中的单元测试事件

javascript - 尝试在 React 中隐藏日历的选择输入和页脚元素

reactjs - combineReducers 不推断类型

reactjs - 在 Material-ui 自动完成组件上设置文本颜色、轮廓和填充