在 Jest 中调用 React 的 this.props.onClick(this) 时我到底应该测试什么?
What exactly should I test when calling React's this.props.onClick(this) in Jest?
我一直在为我的所有事件(当然还有其他所有事件)编写测试,但我不知道如何测试 this.props.onClick(this) 在 child 成分。
我的 child 组件具有以下代码:
closeModal: function() {
this.props.onClick(this);
},
render: function() {
return (
<i className="close-icon" onClick={this.closeModal}></i>
)
}
parent 正在这样听:
onCloseModal: function() {
this.replaceState({
modalStatus: 'hidden'
});
},
render: function() {
return (
<QuestionModal modalStatus={this.state.modalStatus} onClick={this.onCloseModal} />
)
}
我知道如何测试 parent 的点击事件,我也知道如何在测试中调用 child 的按钮点击事件,但我不确定我要做什么应该是准确的测试。
如果我使用 Sinon 和 Jasmine,我会存根 closeModal 方法并检查它是否被调用。我可以用 Jest 做到这一点吗?如果可以,具体怎么做?
更新
我已经尝试根据@PhilVarg 的回答编写一个测试,但我没有走得很远,因为我无法模拟 closeModal。
这是我的测试:
var closeIcon,
myMock = jest.genMockFunction();
form = TestUtils.renderIntoDocument(
<QuestionForm />
);
form.closeModal = myMock;
closeIcon = TestUtils.findRenderedDOMComponentWithClass(form, 'close-icon');
TestUtils.Simulate.click(closeIcon);
expect(form.closeModal).toBeCalled();
预期函数被调用的测试错误。 和 closeModal 没有模拟但仍在运行(我现在有一个控制台登录)。我整个下午都在研究它,但一直无法弄清楚。任何帮助将不胜感激。
如果你想检查函数是否被调用你想使用 jest 的 toBeCalled
function (or toBeCalledWith
). Assuming you've done some set up to instantiate the components, renderIntoDocument, and simulate the click (checkout the tutorial 如果没有)
describe('#closeModal', function(){
beforeEach(function(){
// setup in here to instantiate / render component
// and simulate the click if the i tag
})
it('is called on click', function(){
expect(questionModal.closeModal).toBeCalled()
})
})
编辑:
好的,所以在修补它之后,我能够通过类似于您的原始结构的测试来进行测试。我创建了一个模拟函数,但我没有做 form.closeModal = mock,而是将模拟作为 onClick 道具传递给问题,并检查它是否被调用。
describe('#closeModal', function(){
var mock, form, closeIcon;
beforeEach(function(){
mock = jest.genMockFunction();
form = TestUtils.renderIntoDocument(
<QuestionForm onClick={ mock } />
);
closeIcon = TestUtils.findRenderedDOMComponentWithClass(form, 'close-icon');
TestUtils.Simulate.click(closeIcon);
})
it('is called on click', function(){
expect(mock).toBeCalled()
})
})
您可以使用异步测试。您必须在 onClick
处理程序中调用 done()
。如果一切正常,处理程序将调用 done()
并且测试通过。如果处理程序不会被调用,则测试会在一段时间后失败,因为 Jasmine 无法结束它。
无需存根或嘲笑。
it('should click', function(done) {
function onClick() {
done();
}
var instance = TestUtils.renderIntoDocument(
<Component onClick={onClick} />
);
var button = TestUtils.findRenderedDOMComponentWithTag(instance, 'button');
var buttonDOM = React.findDOMNode(button);
React.addons.TestUtils.Simulate.click(buttonDOM);
});
感谢菲尔的一些建议,我终于弄明白了。我要测试的是单击图标时调用 closeModal。我已经测试过父组件的行为符合预期,但我不知道如何模拟 closeModal,因为我正在测试这个特定的组件,默认情况下,这是 Jest 唯一不为我模拟的组件。我可以手动存根但不知何故不想工作。
我现在所做的是在 closeModal 中模拟 this.props.onClick 并检查它是否触发。
代码如下所示:
describe('QuestionForm', function() {
var onClickFunc,
form;
beforeEach(function() {
onClickFunc = jest.genMockFunction();
form = TestUtils.renderIntoDocument(
<QuestionForm onClick={onClickFunc} />
);
});
it('should call closeModal when the icon is clicked', function() {
var closeIcon = TestUtils.findRenderedDOMComponentWithClass(form, 'close-icon');
TestUtils.Simulate.click(closeIcon);
expect(onClickFunc).toBeCalled();
});
});
我认为这充分测试了 closeModal 的行为是否符合预期。
我一直在为我的所有事件(当然还有其他所有事件)编写测试,但我不知道如何测试 this.props.onClick(this) 在 child 成分。
我的 child 组件具有以下代码:
closeModal: function() {
this.props.onClick(this);
},
render: function() {
return (
<i className="close-icon" onClick={this.closeModal}></i>
)
}
parent 正在这样听:
onCloseModal: function() {
this.replaceState({
modalStatus: 'hidden'
});
},
render: function() {
return (
<QuestionModal modalStatus={this.state.modalStatus} onClick={this.onCloseModal} />
)
}
我知道如何测试 parent 的点击事件,我也知道如何在测试中调用 child 的按钮点击事件,但我不确定我要做什么应该是准确的测试。
如果我使用 Sinon 和 Jasmine,我会存根 closeModal 方法并检查它是否被调用。我可以用 Jest 做到这一点吗?如果可以,具体怎么做?
更新
我已经尝试根据@PhilVarg 的回答编写一个测试,但我没有走得很远,因为我无法模拟 closeModal。
这是我的测试:
var closeIcon,
myMock = jest.genMockFunction();
form = TestUtils.renderIntoDocument(
<QuestionForm />
);
form.closeModal = myMock;
closeIcon = TestUtils.findRenderedDOMComponentWithClass(form, 'close-icon');
TestUtils.Simulate.click(closeIcon);
expect(form.closeModal).toBeCalled();
预期函数被调用的测试错误。 和 closeModal 没有模拟但仍在运行(我现在有一个控制台登录)。我整个下午都在研究它,但一直无法弄清楚。任何帮助将不胜感激。
如果你想检查函数是否被调用你想使用 jest 的 toBeCalled
function (or toBeCalledWith
). Assuming you've done some set up to instantiate the components, renderIntoDocument, and simulate the click (checkout the tutorial 如果没有)
describe('#closeModal', function(){
beforeEach(function(){
// setup in here to instantiate / render component
// and simulate the click if the i tag
})
it('is called on click', function(){
expect(questionModal.closeModal).toBeCalled()
})
})
编辑: 好的,所以在修补它之后,我能够通过类似于您的原始结构的测试来进行测试。我创建了一个模拟函数,但我没有做 form.closeModal = mock,而是将模拟作为 onClick 道具传递给问题,并检查它是否被调用。
describe('#closeModal', function(){
var mock, form, closeIcon;
beforeEach(function(){
mock = jest.genMockFunction();
form = TestUtils.renderIntoDocument(
<QuestionForm onClick={ mock } />
);
closeIcon = TestUtils.findRenderedDOMComponentWithClass(form, 'close-icon');
TestUtils.Simulate.click(closeIcon);
})
it('is called on click', function(){
expect(mock).toBeCalled()
})
})
您可以使用异步测试。您必须在 onClick
处理程序中调用 done()
。如果一切正常,处理程序将调用 done()
并且测试通过。如果处理程序不会被调用,则测试会在一段时间后失败,因为 Jasmine 无法结束它。
无需存根或嘲笑。
it('should click', function(done) {
function onClick() {
done();
}
var instance = TestUtils.renderIntoDocument(
<Component onClick={onClick} />
);
var button = TestUtils.findRenderedDOMComponentWithTag(instance, 'button');
var buttonDOM = React.findDOMNode(button);
React.addons.TestUtils.Simulate.click(buttonDOM);
});
感谢菲尔的一些建议,我终于弄明白了。我要测试的是单击图标时调用 closeModal。我已经测试过父组件的行为符合预期,但我不知道如何模拟 closeModal,因为我正在测试这个特定的组件,默认情况下,这是 Jest 唯一不为我模拟的组件。我可以手动存根但不知何故不想工作。
我现在所做的是在 closeModal 中模拟 this.props.onClick 并检查它是否触发。
代码如下所示:
describe('QuestionForm', function() {
var onClickFunc,
form;
beforeEach(function() {
onClickFunc = jest.genMockFunction();
form = TestUtils.renderIntoDocument(
<QuestionForm onClick={onClickFunc} />
);
});
it('should call closeModal when the icon is clicked', function() {
var closeIcon = TestUtils.findRenderedDOMComponentWithClass(form, 'close-icon');
TestUtils.Simulate.click(closeIcon);
expect(onClickFunc).toBeCalled();
});
});
我认为这充分测试了 closeModal 的行为是否符合预期。