エクスポートされたconst
変数に依存するファイルがあります。この変数はtrue
に設定されますが、必要に応じてfalse
に手動で設定して、ダウンストリームサービスが要求した場合に何らかの動作を防ぐことができます。
const
およびtrue
条件をテストするためにその値を変更できるように、Jestでfalse
変数をモックする方法がわかりません。
例:
//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
});
});
この例は、ES6モジュールの構文をES5にコンパイルすると機能します。これは、最終的に、すべてのモジュールのエクスポートが同じオブジェクトに属し、これを変更できるためです。
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);
});
});
または、raw commonjs require
関数に切り替えて、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);
});
});
ES6 +およびjest 22.1.0+では、ゲッターとspyOnのおかげで別の方法があります。
デフォルトでは、ブール値や数値などのプリミティブ型をスパイできません。ただし、インポートしたファイルを独自のモックに置き換えることができます。ゲッターメソッドは依然としてプリミティブメンバのように動作しますが、スパイすることができます。ターゲットメンバーをスパイすることで、jest.fn()
モックのように、基本的に何でも好きなように実行できます。
例の下
// 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)
})
})