【问题标题】:Can I mock / spy on a variable value that exists in the parent scope of a non-pure function?我可以模拟/监视非纯函数的父范围中存在的变量值吗?
【发布时间】:2020-03-20 13:15:57
【问题描述】:
let state = 'Monday';
export function greet() {
  return 'hello ' + state;
}

↑如果有良好的编码习惯,你不会遇到这样的非纯函数,但出于一些特殊原因,我遇到了。

然后,开玩笑:

import { greet } from './functions';

test('a', () => {
  expect(greet()).toBe('hello Monday');
});

test('b', () => {
  let state = 'Tuesday';
  expect(greet()).toBe('hello Tuesday'); // fail! Still 'hello Monday'
});

在这种情况下,我该如何模拟状态?

【问题讨论】:

  • 您不需要模拟状态,您可以简单地模拟 greet() 并将其设置为返回“你好星期二”。如果你需要在函数(或类)中模拟一些内部的东西,那么你应该使用依赖注入。

标签: javascript mocking jestjs


【解决方案1】:

您可以使用rewire 将模块范围内定义的私有变量替换为模拟变量。

当前版本的 rewire 只兼容 CommonJS 模块。见limitations

所以下面的示例将 ES 模块更改为 CommonJS 模块。

例如 functions.js:

let state = 'Monday';
function greet() {
  return 'hello ' + state;
}

exports.greet = greet;

functions.test.js:

const rewire = require('rewire');
const functions = rewire('./functions');

describe('60763037', () => {
  test('a', () => {
    expect(functions.greet()).toBe('hello Monday');
  });

  test('b', () => {
    functions.__set__('state', 'Tuesday');
    expect(functions.greet()).toBe('hello Tuesday');
  });
});

单元测试结果:

 PASS  stackoverflow/60763037/functions.test.js
  60763037
    ✓ a (3ms)
    ✓ b (1ms)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多