Sinon.stub 在测试中被调用,但期望被调用语句失败
Sinon.stub getting called in test, but expect to be called statement fails
我有一个无状态 React 组件,它有一个我正在尝试测试的 onClick 方法被调用。
我这样做的方法是设置一个具有默认值的道具,指向将在生产中调用的方法,这样我就可以通过 sinon.stub 在我的测试中测试点击事件().
一切顺利。存根被调用。我知道这一点是因为我在存根中添加了 .returns(console.log("called"));
并在控制台中看到了这个打印出来。
但是当涉及到expect(onClickStub).to.have.been.called
时,我的测试失败说它没有被调用。
我的代码涉及一个无状态组件,所以我用一个快速的 TestWrapper class 包装它以进行测试。我不确定上下文是如何工作的,但我不认为这对于测试来说是完全必要的。
这就是全部:
function _handleTabChange(eventKey, id, tabsChange, e) {
e.preventDefault();
tabsChange({ id, eventKey });
console.log("clicked");
}
const _Tab = ({ onClick = _handleTabChange, eventKey, children, ...props }, { activeKey, parentContainer, tabsChange }) => (
<li className={classNames('b-tab', { active: eventKey === activeKey })} {...props}>
<a href="#"
role="tab"
data-toggle="tab"
onClick={onClick.bind(this, eventKey, parentContainer, tabsChange)}>
{children}
</a>
</li>
);
it('onclick event', () =>{
const props = {
tabsAddContainer : sinon.spy(),
tabsRemoveContainer : sinon.spy(),
tabsChange : sinon.stub(),
tabs : {},
tabContainerID : 'company-management-tabs',
onClick: sinon.stub.returns(console.log("HELLO")),
}
const onClickStub = sinon.stub.returns(console.log("HELLO"));
class TestWrapper extends React.Component {
render() {
return <Tab {...props} {...context} />
}
}
const renderTab = TestUtils.renderIntoDocument(
<TestWrapper onClick={onClickStub} tabsChange={props.tabsChange} active={true} context={{tabsChange: function(){}, parentContainer:"parent-container"}}/>
)
const tabElements = TestUtils.scryRenderedDOMComponentsWithTag(renderTab, "a");
console.log("tabElements", tabElements);
TestUtils.Simulate.click(tabElements[0], {});
expect(onClickStub).to.have.been.called
});
嗯,这与 onClick 调用中的 .bind 有关。解决方案是组织道具以接受 sinon 存根,但在所有其他生产情况下,默认调用 _handleTabChange 函数。
这意味着 handleTabChange 必须 return 一个函数。
现在它在测试中正确注册了 sinon.stub,在生产中调用 _handleTabChange 而无需 .bind。
我有一个无状态 React 组件,它有一个我正在尝试测试的 onClick 方法被调用。
我这样做的方法是设置一个具有默认值的道具,指向将在生产中调用的方法,这样我就可以通过 sinon.stub 在我的测试中测试点击事件().
一切顺利。存根被调用。我知道这一点是因为我在存根中添加了 .returns(console.log("called"));
并在控制台中看到了这个打印出来。
但是当涉及到expect(onClickStub).to.have.been.called
时,我的测试失败说它没有被调用。
我的代码涉及一个无状态组件,所以我用一个快速的 TestWrapper class 包装它以进行测试。我不确定上下文是如何工作的,但我不认为这对于测试来说是完全必要的。
这就是全部:
function _handleTabChange(eventKey, id, tabsChange, e) {
e.preventDefault();
tabsChange({ id, eventKey });
console.log("clicked");
}
const _Tab = ({ onClick = _handleTabChange, eventKey, children, ...props }, { activeKey, parentContainer, tabsChange }) => (
<li className={classNames('b-tab', { active: eventKey === activeKey })} {...props}>
<a href="#"
role="tab"
data-toggle="tab"
onClick={onClick.bind(this, eventKey, parentContainer, tabsChange)}>
{children}
</a>
</li>
);
it('onclick event', () =>{
const props = {
tabsAddContainer : sinon.spy(),
tabsRemoveContainer : sinon.spy(),
tabsChange : sinon.stub(),
tabs : {},
tabContainerID : 'company-management-tabs',
onClick: sinon.stub.returns(console.log("HELLO")),
}
const onClickStub = sinon.stub.returns(console.log("HELLO"));
class TestWrapper extends React.Component {
render() {
return <Tab {...props} {...context} />
}
}
const renderTab = TestUtils.renderIntoDocument(
<TestWrapper onClick={onClickStub} tabsChange={props.tabsChange} active={true} context={{tabsChange: function(){}, parentContainer:"parent-container"}}/>
)
const tabElements = TestUtils.scryRenderedDOMComponentsWithTag(renderTab, "a");
console.log("tabElements", tabElements);
TestUtils.Simulate.click(tabElements[0], {});
expect(onClickStub).to.have.been.called
});
嗯,这与 onClick 调用中的 .bind 有关。解决方案是组织道具以接受 sinon 存根,但在所有其他生产情况下,默认调用 _handleTabChange 函数。
这意味着 handleTabChange 必须 return 一个函数。
现在它在测试中正确注册了 sinon.stub,在生产中调用 _handleTabChange 而无需 .bind。