【问题标题】:How to mock an import class used in the class I want to test?如何模拟我要测试的类中使用的导入类?
【发布时间】:2020-10-14 16:09:31
【问题描述】:

如何模拟在我要测试的类中使用的导入类?

我的代码如下:

Bird.js

export default class Bird {
  constructor() {...}
  tweet() {...}
}

Nest.js

import Bird from 'Bird.js'
export default class Nest {
  spawn() {
    this.bird = new Bird()
    this.bird.tweet()
  }
} 

我想测试spawn 是否真的可以调用tweet,所以我想模拟整个Bird 类。我试过了:

Nest.spec.js

jest.mock('<some_path>/Bird.js')
import Nest from '<some_path>/Nest.js'
test('...', () => {
  const nest = new Nest()
  nest.spawn()
  expect(this.bird.tweet).toBeCalledTimes(1)
})

不过,Nest.spawn() 调用了this.bird.tweet(),但似乎jest.mock('&lt;some_path&gt;/Bird.js') 不会影响Nest.js 中的import Bird from 'Bird.js'

也就是说,它仍然导入原始类,tweet 具有原始行为而不是jest.fn()

【问题讨论】:

    标签: javascript unit-testing mocking jestjs vue-test-utils


    【解决方案1】:

    作为我正在遵循的一种做法,模拟您的实现是一种不好的做法,因为当您更改 Bird 的实现时,您对 Nest 的测试将不会中断,因为他们使用的是您的模拟版本。

    更好的方法是测试推文的副作用。 (您可以考虑这个问题:“生成嵌套时应该发生什么 -> 它应该执行推文所做的事情)。使用这种方法,您不是在测试“推文所做的事情”是如何发生的(通过调用 tweet),而是会发生什么当你生成时。

    解释有点抽象,我试着举例说明一下:

    假设tweet 正在发出声音(这是我们的产品定义的副作用,发出声音 = console.log('twit....')),所以我的测试将如下所示:

    import Nest from '<some_path>/Nest.js'
    test('...', () => {
      jest.spyOn(console, 'log');
      const nest = new Nest()
      nest.spawn()
      expect(console.log).toBeCalledWith('twit....');
    })
    

    我不在乎副作用是如何发生的。这使您的测试对于未来的变化更加健壮。此外,它消除了为您的真实实现管理模拟实现的需要。

    只是测试你的副作用:]

    【讨论】:

      猜你喜欢
      • 2019-10-26
      • 2021-02-10
      • 2020-01-01
      • 2018-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-05
      相关资源
      最近更新 更多