Jest - 从es6类中模拟单个函数

时间:2018-04-04 13:33:35

标签: unit-testing jestjs es6-class

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

设定:

// MyClass.js

export default class MyClass {
   constructor () { ... }
   foo() {
      ...
      bar()
   }
   bar() { 
      ... 
   }
}

所以我正在测试foo()但是作为测试的一部分,我想确保调用bar()。我可以看到如果bar()是一个外部依赖项我怎么能这样做,因为我可以嘲笑那个但是因为它是我正在测试的类的一部分我不能模拟整个类,否则我不会&# 39;在我的测试中调用一个具体的实现。

我希望这会完成这个伎俩(按照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()
})

我也尝试在MyClass的实例化版本上模拟该方法(即myClass.bar = mockBar),但都没有给出所需的结果。

这种嘲讽结构是否可以通过玩笑?

1 个答案:

答案 0 :(得分:5)

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

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()
})

这是因为ES6类只是简单的Javascript原型模型,而且

class MyClass {
  bar() {}
}

等同于

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

  return MyClass;
}();

但要

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

  return MyClass;
}();