与摩卡手表一起使用时,Sinon 存根有奇怪的行为

Sinon stub has weird behavior when used with mocha watch

这是我们的基本设置

src/MyComponent.js

import actions from `src/actions`

 export const mapDispatchToProps = dispatch => {
    return {
      onClick: () => {
        dispatch(actions.myAction())
      }
    }
 }

src/actions.js

const actions = { 
  myAction: () => () => ...
}
export default actions

src/MyComponentTest.js

 import sinon from 'sinon'
 import actions from 'src/actions'
 import { mapDispatchToProps } from 'src/MyComponent'

 describe('onClickTests, () => {
   let dispatch = sinon.spy()
   let onClick

   beforeEach(() => {
     onClick = mapDispatchToProps(dispatch).onClick
   })

   it('calls dispatch with myAction', () => {
     function f () {}
     sinon.stub(actions, 'myAction').returns(f)
     onClick()
     expect(dispatch.args[0]).to.deep.equal([f])
   })
 })

基本上,我们正在检查 onClick 函数是否正在使用 actions.myAction 的 return 值调用 dispatch。由于真正的 actions.myAction return 是一个匿名函数,我们将它存根到 return 函数 f。当我们 运行 使用 Mocha 时一切正常,直到我们 运行 使用 --watch。第一个 运行 仍然按预期通过,但是当我们保存测试并且测试重新 运行 时,此测试失败

expected [ [Function: f] ] to deeply equal [ [Function: f] ]

如果我对测试进行了这些更改

   it('calls dispatch with myAction', () => {
     function f () {}
     sinon.stub(actions, 'myAction').returns(2)
     onClick()
     expect(dispatch.args[0]).to.deep.equal([2])
   })

我明白了

expected [ [Function: f] ] to deeply equal [ [2] ]

所以我从中收集到的是,在第二个 运行 上,actions.minimize return 编辑的 f 是 "old" f 从第一个 运行。我们已经尝试了多种不同的变体,比如使用 module.exports/require 而不是 export/import 并将内容移动到 Mocha 挂钩(beforeEach 等)中,但似乎没有任何效果,这让我相信这是我们测试方式的一个更基本的问题。有什么建议吗?

我以前遇到过这个问题,花了一段时间才弄明白。

不确定你的情况是否如此,但我对我的组件使用了 .jsx 扩展,结果发现这会带来各种随机问题。

Component.jsx 重命名为 Component.js 解决了问题。