Sinon stub 仅在 运行 之前记录 react 调用

Sinon stub only records react calls if it has been run before

这是我正在测试的代码:

const CardWarsComponent = props => {
    const onSubmitCardMove = () => {
        props.floopThePig()
    }
    return <Button id="FloopButtonId" onClick={onSubmitCardMove}>FLOOP IT</Button>
};

当我测试时我这样做:

const floopStub = sinon.stub();
const wrapper = shallow(<CardWarsComponent floopThePig={floopStub}></CardWarsComponent>)
const button = wrapper.find('#FloopButtonId').dive();
const onClick = button.prop('onClick');
onClick();
wrapper.update();
expect(floopStub).to.have.been.calledOnce();

我发现我收到了这样的回复:

TypeError: (0, _chai.expect)(...).to.have.been.calledOnce is not a function

但是,如果我已经调用过一次:

const floopStub = sinon.stub();
floopStub()
const wrapper = shallow(<CardWarsComponent floopThePig={floopMock}></CardWarsComponent>)

然后我得到:

 expected floopThePig to have been called exactly once, but was called twice
floopThePig at Context.floopThePig
floopThePig at floopThePig

那么为什么我不能调用它一次,但是在调用一次之后......我得到了第二次(实际测试)调用?

您收到的初始错误消息完全正确 - 查看 the Sinon docs.calledOnce 不是函数,它是运行代码的 javascript get。一般来说,Chai 期望似乎只有在需要参数时才是函数。

我觉得这有点烦人,因为 get 重载不是很好并且破坏了我们推理代码的能力,并且它引发了一堆 lint 错误,但是嘿嘿。

将您的期望更改为

expect(floopStub).to.have.been.calledOnce;

修复测试(至少在我的机器上!)

在你的第二个例子中代码似乎 "work" 的原因是因为测试解决了 calledOnce get 操作,它检查条件并抛出测试失败断言,所以永远没有机会通过尝试调用 get 结果来抛出原始错误,就好像它是一个函数一样。

顺便说一下,使用酶的内置 .simulate() 调用更容易触发点击事件。此代码工作正常:

const floopStub = sinon.stub();
const wrapper = shallow(<CardWarsComponent floopThePig={floopMock}></CardWarsComponent>);
wrapper.find('#FloopButtonId').dive().simulate('click');
expect(floopStub).to.have.been.calledOnce;

可以在此处找到有关使用 sinon/enzyme 测试 React 事件的更多信息:https://www.leighhalliday.com/testing-react-jest-enzyme-sinon