Unit testing 使用Material UI对话框对组件进行单元测试

Unit testing 使用Material UI对话框对组件进行单元测试,unit-testing,reactjs,material-ui,reactjs-testutils,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._conf

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

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

<FlatButton
  label="Cancel"
  secondary={true}
  onTouchTap={this._cancelDialog.bind(this)} 
 />
 <FlatButton
   label="Submit"
   primary={true}
   onTouchTap={this._confirmDialog.bind(this)} 
 />
在上面的例子中,cancelButton是正确的DOM元素。Simulate.click不会触发组件单击功能

问候
乔纳斯

我遇到了同样的问题,并这样解决了它:

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();
const myMock=jest.genMockFunction();
常量matcherComponent=TestUtils.renderIntoDocument(
);
const raisedButton=TestUtils.findRenderedComponentWithType(
火柴组件,升起按钮);
TestUtils.Simulate.click(ReactDOM.findDOMNode(raisedButton.firstChild));
expect(myMock).toBeCalled();

这对我来说很好。然而,我仍然在与Simulate.change进行斗争

也遇到了同样的问题。我查看了源代码,对话框组件的render方法实际上创建了组件的一个实例
RenderToLayer
。此组件的行为类似于门户,通过在其“render”函数中返回null,而不是直接附加到主体,来破坏react的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)
现在您可以使用
npmtest
运行mocha测试,并使用
npmrundebug
进入调试器。一旦进入调试器,它将立即暂停并等待您输入断点。此时,输入
c
继续。现在您可以放置
调试器语句,以生成调试器将响应的断点。一旦找到断点,它将暂停并允许您使用本地作用域使用代码。此时,输入
repl
以输入代码的本地范围并访问本地变量

也许您不需要调试器,但也许其他人会觉得这很有用。祝你好运,快乐

解决方法如下:

/*
* 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);
var component = TestUtils.renderIntoDocument(
  <MuiThemeProvider muiTheme={getMuiTheme()}>
    <UserInteractions.signupDialog show={true}/>
  </MuiThemeProvider>
);

var dialogComponent = TestUtils.findRenderedComponentWithType(component, UserInteractions.signupDialog);

var dialog = TestUtils.renderIntoDocument(
  <MuiThemeProvider muiTheme={getMuiTheme()}>
    {dialogComponent.refs.dialog.renderLayer()}
  </MuiThemeProvider>
);

var node = React.findDOMNode(dialog);
/*
*我想确认,当我单击“取消”按钮时,我的showModal状态是否设置为*false
*/
//浅层渲染我的组件有对话框
const wrapper=shallow().dive();
//将showModal状态设置为true
setState({showmodel:true});
//从actions中找到id为“cancelBtn”对象的cancel按钮,并调用onTouchTap模拟按钮单击
wrapper.find('Dialog').props().actions.find((elem)=>(elem.props.id='cancelBtn')).props.onTouchTap();
//验证showModal状态是否设置为false
expect(wrapper.state('showModal')).toBe(false);
非常好。但我还有一个补充。如果您尝试应用此解决方案并出现错误:

错误:“警告:失败的上下文类型:已标记上下文
muiTheme
。” 根据
对话框inline
中的要求,但其值为
未定义

您应按如下方式修改代码:

/*
* 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);
var component = TestUtils.renderIntoDocument(
  <MuiThemeProvider muiTheme={getMuiTheme()}>
    <UserInteractions.signupDialog show={true}/>
  </MuiThemeProvider>
);

var dialogComponent = TestUtils.findRenderedComponentWithType(component, UserInteractions.signupDialog);

var dialog = TestUtils.renderIntoDocument(
  <MuiThemeProvider muiTheme={getMuiTheme()}>
    {dialogComponent.refs.dialog.renderLayer()}
  </MuiThemeProvider>
);

var node = React.findDOMNode(dialog);
var component=TestUtils.renderIntoDocument(
);
var dialogComponent=TestUtils.findenderedcomponentwithtype(component,UserInteractions.signupDialog);
var dialog=TestUtils.renderIntoDocument(
{dialogComponent.refs.dialog.renderLayer()}
);
var node=React.findDOMNode(对话框);

两种酶法。您需要使用
createMount
createshall
带俯冲选项

是否可以将您的问题更改为更清晰的格式?感谢您的回答。不幸的是,TestUtils.findRenderedComponentWithType(dialog,FlatButton)不会在对话框中返回任何内容。我自己在dialog中也遇到了同样的问题。。可能是材质UI的对话框有问题吗?我用对话框测试来解决这个问题已经有一段时间了。回答得很好。谢谢你。
var component = TestUtils.renderIntoDocument(
  <MuiThemeProvider muiTheme={getMuiTheme()}>
    <UserInteractions.signupDialog show={true}/>
  </MuiThemeProvider>
);

var dialogComponent = TestUtils.findRenderedComponentWithType(component, UserInteractions.signupDialog);

var dialog = TestUtils.renderIntoDocument(
  <MuiThemeProvider muiTheme={getMuiTheme()}>
    {dialogComponent.refs.dialog.renderLayer()}
  </MuiThemeProvider>
);

var node = React.findDOMNode(dialog);