【问题标题】:How to access global constant in unit tests with Jest?如何使用 Jest 在单元测试中访问全局常量?
【发布时间】:2017-09-15 15:49:12
【问题描述】:

我想模拟一个全局变量并测试它是否在我的函数中被调用。在我的文件中,我定义了一个全局变量“remote”,它实例化了一个主题(RxJS 库)。我只是想测试是否使用正确的参数“名称”调用了 Subject 的下一个函数。但是,我无法访问测试文件中的全局变量 remote。我试图在我的设置文件中模拟它,但不起作用。

我该怎么做?

const remote = new Subject();
const analytics = {
  click: (name) => {
    if (name) {
      remote.next(name);
    }
  }
}
module.exports = analytics;

谢谢!

【问题讨论】:

  • 我猜你用的是webpack,remote不是全局变量
  • 嘿@Zen 感谢您的回答。是的,我正在使用 webpack。 Jest 告诉我它不知道新 Subject 的属性“next”(如果您对 observables 有所了解,next 是 Subject 类的经典方法)。关于如何让 Jest 了解“远程”变量的任何想法?

标签: unit-testing testing mocking rxjs jestjs


【解决方案1】:

这是个好问题。当您使用 webpack 时,您的个人文件被包装到不同的函数调用中。看看这个doc
这个问题最好的部分是,如果您希望您的代码可测试,它显示了 IOC/DI 的必要性。您可以导出一个Analytics 类,然后将remote 注入其构造函数,而不是在本地模块中定义remote

// Analytics.js
export default class Analytics{
  constructor(remote) {
    this.remote = remote
  }

  click(name) {
    if (name) {
      this.remote.next(name)
    }
  }
}

main.js
import Analytics from './Analytics'

const remote = new Subject()
const analytics = new Analytics(remote)
analysis.click('foo')

将依赖项注入所有组件/服务会很乏味。 Angular 有 an decent doc 说明为什么/如何简化它。希望这有帮助!

// 更新
您可以使用 window 定义全局常量并在测试中使用window.remote 访问它

const remote = new Subject()
window.remote = remote

当你想模拟远程时,记得修改它的属性而不是对它的引用。

// test.js
beforeEach(() => {
    // wrong !!!
    window.remote = {
        next(name) { assert(name) }
    }

    // right
    window.remote.next = name => assert(name)
})

【讨论】:

  • 非常感谢! NodeJS 文档非常有用。我同意这个解决方案是最好的;但是我正在使用无法重构的遗留代码......知道我该如何测试它吗?
  • 谢谢@Zen,我去看看!
猜你喜欢
  • 2016-05-28
  • 1970-01-01
  • 2015-07-25
  • 1970-01-01
  • 1970-01-01
  • 2018-12-15
  • 2020-01-21
  • 1970-01-01
  • 2020-09-25
相关资源
最近更新 更多