0

I'm trying to change the value of a primitive config object during tests. One of my files under test re-exports a primitive that is conditional on the config values.

I'm finding that when the value is wrapped in a function, then mocking it and asserting on it works perfectly.

However when the value is re-exported as a primitive, the value is not mocked, and is undefined.

Simplified example:

config.ts

export const config = {
  environment: 'test'
};

app.ts

import { config } from './config';

export const app = () => config.environment;

export const environment = config.environment;

app.spec.ts

import { app, environment } from './app';
import * as config from './config';

jest.mock('./config', () => ({
  config: {},
}));

beforeEach(() => {
  jest.resetAllMocks();
});

const mockConfig = config.config as jest.Mocked<typeof config.config>;

test('app', () => {
  mockConfig.environment = 'prod';
  expect(app()).toEqual('prod');
});

test('environment', () => {
  mockConfig.environment = 'nonprod';
  expect(environment).toEqual('nonprod');
});

The first test passes, but the second test "environment" fails. Why?

✕ environment (3 ms)

  ● environment

    expect(received).toEqual(expected) // deep equality

    Expected: "nonprod"
    Received: undefined

      19 | test('environment', () => {
      20 |   mockConfig.environment = 'nonprod';
    > 21 |   expect(environment).toEqual('nonprod');
         |                             ^
      22 | });
      23 |

      at Object.<anonymous> (config/app.spec.ts:21:29)
Misha Bruml
  • 129
  • 5
  • Objects are passed by reference. Primitives are passed by value. – Konrad Nov 10 '22 at 15:59
  • 1
    Does this answer your question? [Pass variables by reference in JavaScript](https://stackoverflow.com/questions/7744611/pass-variables-by-reference-in-javascript) – Konrad Nov 10 '22 at 15:59
  • 1
    `mockConfig` holds a **reference** to the `config` object exported from `config.ts`. When you change `mockConfig` it changes `config` too. `environment` holds a **value** that is whatever `config.environment` was initialised with (`undefined`). As it doesn't hold a reference, it never changes. – Wing Nov 10 '22 at 16:01

1 Answers1

0

The problem could be related with the order files are read. The app file is the first one to be read, and then the config file is read because its imported on the app one. But, probably the app code run first, so the variable was set as undefined (because the config one had not a value at the time).

The same does not happen with the app function, because it reads the config variable only after the function is called. And at that time, the variable already was set.

Diogo Laia
  • 97
  • 5