ZYinMD
ZYinMD

Reputation: 5109

Can I mock / spy on a variable value that exists in the parent scope of a non-pure function?

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

↑ With good coding practice, you wouldn't encounter non-pure functions like this, but for some special reasons I did.

Then, with jest:

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'
});

In this case, how can I mock the state?

Upvotes: 1

Views: 1412

Answers (1)

Lin Du
Lin Du

Reputation: 102457

You can use rewire to replace the private variable defined in the module scope with a mocking one.

The current version of rewire is only compatible with CommonJS modules. see limitations

So below example change the ES module to CommonJS modules.

E.g. 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');
  });
});

unit test results:

 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

Upvotes: 2

Related Questions