开玩笑:如何在使用module.exports

时间:2019-04-24 02:38:12

标签: javascript node.js jestjs

我正在尝试使用module.exports时模拟一个特定的功能。我如何测试内部函数B?

在我的worker.js中

module.exports = function () {
  this.funcA = funcA
  this.funcB = funcB
}

funcA () {
  funcB()
}

funcB() {...}

在我的worker-test.js中

const Worker = require('./worker')

test('test functionB', () => {...}) 

test('test functionA', () => {
  const work = new Worker()
  work.funcB = jest.fn()  //mock funcB
  work.funcA  //run funcA

  expect(work.funcB).toHaveBeenCalledTimes(1) //Error
}) 

我是开玩笑的新手。在这种情况下,有什么好的方法可以模拟函数?

2 个答案:

答案 0 :(得分:1)

funcB直接调用funcA以来,没有一种方法可以模拟funcB的当前代码编写方式。

最简单的解决方法是注意worker.js返回一个构造函数,而funcAfuncB几乎是 prototype methods

...如果使它们成为原型方法,则可以模拟funcB

worker.js

class Worker {
  funcA() {
    this.funcB();
  }
  funcB() {
    throw new Error('should not make it here');
  }
}

module.exports = Worker;

worker.test.js

const Worker = require('./worker');

test('test functionB', () => { /* ... */ })

test('test functionA', () => {
  const spy = jest.spyOn(Worker.prototype, 'funcB');  // <= spy on funcB
  spy.mockImplementation(() => {});  // <= mock funcB

  const work = new Worker();
  work.funcA();  // <= call funcA

  expect(spy).toHaveBeenCalledTimes(1);  // Success!
  spy.mockRestore();  // <= restore funcB
}) 

答案 1 :(得分:0)

我知道这是一个老问题,但我想我会插话,因为我也在寻找一种方法来做到这一点,并且发现它实际上是可能的。

不是像上面那样调用 javascript 函数,而是需要给它 this 的作用域,以确保在模拟 funcB 时,funcA 调用模拟版本而不是只是函数本身。

这意味着 worker.js 变成

module.exports = function () {
  this.funcA = funcA
  this.funcB = funcB
}

funcA () {
  this.funcB()
}

funcB() {/* Your impl */}

并且 worker.test.js 可以保留,就像以前一样:

const Worker = require('./worker')

test('test functionB', () => {...}) 

test('test functionA', () => {
  // You could even just have: const work = require('./worker')
  const work = new Worker()
  work.funcB = jest.fn()  //mock funcB
  work.funcA()  //run funcA

  expect(work.funcB).toHaveBeenCalledTimes(1)
})