web-dev-qa-db-fra.com

Comment se moquer d'un const exporté

J'ai un fichier qui repose sur une variable exportée const. Cette variable est définie sur true, mais si nécessaire, vous pouvez la définir manuellement sur false pour éviter certains comportements si les services en aval le demandent.

Je ne suis pas sûr de savoir comment simuler une variable const dans Jest afin de pouvoir changer sa valeur pour tester les conditions true et false.

Exemple:

//constants module
export const ENABLED = true;

//allowThrough module
import { ENABLED } from './constants';

export function allowThrough(data) {
  return (data && ENABLED === true)
}

// jest test
import { allowThrough } from './allowThrough';
import { ENABLED } from './constants';

describe('allowThrough', () => {
  test('success', () => {
    expect(ENABLED).toBE(true);
    expect(allowThrough({value: 1})).toBe(true);
  });

  test('fail, ENABLED === false', () => {
    //how do I override the value of ENABLED here?

    expect(ENABLED).toBe(false) // won't work because enabled is a const
    expect(allowThrough({value: 1})).toBe(true); //fails because ENABLED is still true
  });
});
29
Mdd

Cet exemple fonctionnera si vous compilez la syntaxe des modules ES6 dans ES5, car au final, toutes les exportations de modules appartiennent au même objet, qui peut être modifié.

import { allowThrough } from './allowThrough';
import { ENABLED } from './constants';
import * as constants from './constants';

describe('allowThrough', () => {
    test('success', () => {
        constants.ENABLED = true;

        expect(ENABLED).toBe(true);
        expect(allowThrough({ value: 1 })).toBe(true);
    });

    test('fail, ENABLED === false', () => {
        constants.ENABLED = false;

        expect(ENABLED).toBe(false);
        expect(allowThrough({ value: 1 })).toBe(false);
    });
});

Alternativement, vous pouvez passer à la fonction raw commonjs require, et le faire comme ceci à l'aide de jest.mock(...):

const mockTrue = { ENABLED: true };
const mockFalse = { ENABLED: false };

describe('allowThrough', () => {
    beforeEach(() => {
        jest.resetModules();
    });

    test('success', () => {
        jest.mock('./constants', () => mockTrue)
        const { ENABLED } = require('./constants');
        const { allowThrough } = require('./allowThrough');

        expect(ENABLED).toBe(true);
        expect(allowThrough({ value: 1 })).toBe(true);
    });

    test('fail, ENABLED === false', () => {
        jest.mock('./constants', () => mockFalse)
        const { ENABLED } = require('./constants');
        const { allowThrough } = require('./allowThrough');

        expect(ENABLED).toBe(false);
        expect(allowThrough({ value: 1 })).toBe(false);
    });
});
29
eur00t

Il y a une autre façon de le faire dans ES6 + et dans Jest 22.1.0+ grâce aux getters et à spyOn.

Par défaut, vous ne pouvez pas espionner les types primitifs tels que boolean ou number. Vous pouvez cependant remplacer un fichier importé par votre propre maquette. Une méthode de lecture agit toujours comme un membre primitif mais nous permet de l'espionner. En ayant un espion sur notre membre cible, vous pouvez en faire ce que vous voulez, comme avec un jest.fn() mock.

Ci-dessous un exemple

// foo.js
export const foo = true; // could be expression as well
// subject.js
import { foo } from './foo'

export default () => foo
// subject.spec.js
import subject from './subject'

jest.mock('./foo', () => ({
  get foo () {
    return true // set some default value
  }
}))

describe('subject', () => {
  const mySpy = jest.spyOn(subject.default, 'foo', 'get')

  it('foo returns true', () => {
    expect(subject.foo).toBe(true)
  })

  it('foo returns false', () => {
    mySpy.mockReturnValueOnce(false)
    expect(subject.foo).toBe(false)
  })
})

Lire la suite dans la documentation.

5
Luke