【问题标题】:How do you mock a module-scoped variable in Jest?你如何在 Jest 中模拟一个模块范围的变量?
【发布时间】:2021-07-06 17:45:25
【问题描述】:

考虑以下函数:

let dictionary = {
  there: "there"
}

function sayHi(word){
  if (dictionary.hasOwnProperty(word)){
    return "hello " + dictionary[word] 
  }
}

如果我想测试 sayHi 函数,我将如何在 Jest 测试中模拟 dictionary 变量?

我尝试从模块中导入所有内容并覆盖字典对象,但没有奏效,同样我尝试将其模拟为函数,但仍然无法使其工作。

【问题讨论】:

  • 简而言之,你不会。如果您认为字典是 sayHi 的合作者,而不仅仅是实现细节,请将其移出模块。
  • 嗨@jonrsharpe,感谢您的评论。我会看看我是否可以以不同的方式组织代码。
  • 在这种情况下,它似乎是静态数据,所以我将其视为实现细节。
  • 嗨@jonrsharpe,很抱歉我不知道,但我将如何在测试中做到这一点?
  • 您不必做任何特别的事情,这就是重点。你测试例如expect(sayHi("there")).toEqual("there") 并且不要过多考虑是否有对象映射或开关或一堆 ifs 或只是 const sayHi = () => "there"

标签: javascript testing jestjs mocking


【解决方案1】:

您可以使用rewire 包来覆盖模块内的变量。

例如

index.js:

let dictionary = {
  there: 'there',
};

function sayHi(word) {
  if (dictionary.hasOwnProperty(word)) {
    return 'hello ' + dictionary[word];
  }
}

module.exports = { sayHi };

index.test.js:

const rewire = require('rewire');

describe('67044925', () => {
  it('should pass', () => {
    const mod = rewire('./');
    mod.__set__('dictionary', { there: 'teresa teng' });
    const actual = mod.sayHi('there');
    expect(actual).toEqual('hello teresa teng');
  });

  it('should pass too', () => {
    const mod = rewire('./');
    mod.__set__('dictionary', { there: 'slideshowp2' });
    const actual = mod.sayHi('there');
    expect(actual).toEqual('hello slideshowp2');
  });
});

单元测试结果:

 PASS  examples/67044925/index.test.js (12.148 s)
  67044925
    ✓ should pass (15 ms)
    ✓ should pass too (4 ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        14.047 s

【讨论】:

  • “仅仅因为你可以,并不意味着你应该。” 进入模块边界会破坏封装,dictionary(特别是在你的示例中,它显然没有导出) 实际上是模块的私有
猜你喜欢
  • 2021-12-04
  • 2019-09-10
  • 1970-01-01
  • 2022-08-17
  • 2021-10-09
  • 2015-11-17
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
相关资源
最近更新 更多