开玩笑-模拟es6类的单个函数

Bau*_*a23 2 unit-testing jestjs es6-class

我想测试是否从正在测试的函数中调用了某个特定函数,但是这两个函数都在我正在测试的es6类中。

设定:

// MyClass.js

export default class MyClass {
   constructor () { ... }
   foo() {
      ...
      bar()
   }
   bar() { 
      ... 
   }
}
Run Code Online (Sandbox Code Playgroud)

所以我正在测试foo(),但是作为测试的一部分,我想确保调用bar()。我可以看到如果bar()是一个外部依赖关系,该如何做呢?在我的测试中。

我希望这能做到这一点(按照https://facebook.github.io/jest/docs/en/es6-class-mocks.html),但无济于事:

// MyClass.spec.js

jest.unmock('./MyClass')
import MyClass from './MyClass'  
...
test('my test', () => {
   var mockBar = jest.fn()
   MyClass.bar = mockBar   

   var myClass = new MyClass()
   myClass.foo()

   expect(mockBar).toHaveBeenCalled()
})
Run Code Online (Sandbox Code Playgroud)

我还尝试在MyClass的实例化版本(即myClass.bar = mockBar)上模拟该方法,但均未给出期望的结果。

这个玩笑的结构有可能开玩笑吗?

And*_*nko 6

在测试ES6类的特定方法(不是类实例)时,您不应模拟该类的属性,而应模拟该类原型的属性。

jest.unmock('./MyClass')
import MyClass from './MyClass'  
...
test('my test', () => {
  var mockBar = jest.fn()
  MyClass.prototype.bar = mockBar // here's the difference   

  var myClass = new MyClass()
  myClass.foo()

  expect(mockBar).toHaveBeenCalled()
})
Run Code Online (Sandbox Code Playgroud)

这是因为ES6类只是纯Javascript原型模型上的糖,并且

class MyClass {
  bar() {}
}
Run Code Online (Sandbox Code Playgroud)

等价于

var MyClass = function () {
  MyClass.bar = function bar() {};

  return MyClass;
}();
Run Code Online (Sandbox Code Playgroud)

但是

var MyClass = function () {
  MyClass.prototype.bar = function bar() {};

  return MyClass;
}();
Run Code Online (Sandbox Code Playgroud)