【问题标题】:Jest: How to mock one specific function when using module.exports笑话:如何在使用 module.exports 时模拟一个特定的功能
【发布时间】:2019-04-24 02:38:12
【问题描述】:

我试图在使用 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
}) 

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

【问题讨论】:

标签: javascript node.js jestjs


【解决方案1】:

由于funcA 直接调用funcB,因此无法像当前编写代码的方式那样模拟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
}) 

【讨论】:

  • 我尝试将我的所有功能分解为模块。小模块很容易模拟,但我认为我应该用类重写我的worker.js。谢谢!
【解决方案2】:

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

您需要为其提供this 的范围,以确保在模拟funcB 时,funcA 调用模拟版本而不是仅调用函数本身,而不是像上面那样调用javascript 函数。

这意味着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)
}) 

【讨论】:

    猜你喜欢
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多