The Jest Object
jest
オブジェクトは、すべてのテストファイル内で自動的にスコープされます。 jest
オブジェクトのメソッドはモックの作成に役立ち、Jestの全体的な動作を制御できます。 import {jest} from '@jest/globals'
を介して明示的にインポートすることもできます。
モックモジュール
jest.disableAutomock()
モジュールローダーの自動モック機能を無効にします。
詳細については、configurationの
automock
セクションも参照してください。
このメソッドが呼び出された後は、すべての require()
関数は各モジュールの (モックではなく) の本物を返すようになります。
Jest の設定:
{
"automock": true
}
例:
// utils.js
export default {
authorize: () => {
return 'token';
},
};
// __tests__/disableAutomocking.js
import utils from '../utils';
jest.disableAutomock();
test('original implementation', () => {
// now we have the original implementation,
// even if we set the automocking in a jest configuration
expect(utils.authorize()).toBe('token');
});
この関数はモックしたい依存関係が、モックが要らないものよりもはるかに少ないシナリオがある場合に便利です。 例えば、"implementation details"として分類されるのが妥当な大量の依存関係を持つモジュールのテスト書く場合、それらをモックしたいとは思わないでしょう。
Examples of dependencies that might be considered "implementation details" are things ranging from language built-ins (e.g. Array.prototype methods) to highly common utility methods (e.g. underscore/lo-dash, array utilities, etc) and entire libraries like React.js.
メソッドチェーンのためにjest
オブジェクトを返します。
注意: このメソッドは以前はautoMockOff
と呼ばれていました。 babel-jest
を使用している場合は、disableAutomock
の呼び出しは自動的にコードの先頭で行われます。 この動作を避けるにはautoMockOff
を明示的に使用して下さい。
jest.enableAutomock()
モジュールローダーで自動モック機能を有効化します。
メソッドチェーンのためにjest
オブジェクトを返します。
詳細については、configurationの
automock
セクションも参照してください。
例:
// utils.js
export default {
authorize: () => {
return 'token';
},
isAuthorized: secret => secret === 'wizard',
};
// __tests__/enableAutomocking.js
jest.enableAutomock();
import utils from '../utils';
test('original implementation', () => {
// ここではモック化されています
expect(utils.authorize._isMockFunction).toBeTruthy();
expect(utils.isAuthorized._isMockFunction).toBeTruthy();
});
注意: このメソッドは以前はautoMockOn
と呼ばれていました。 babel-jest
を使用している場合は、enableAutomock
の呼び出しは自動的にコードの先頭で行われます。 この動作を避けるにはautoMockOn
を明示的に使用して下さい。
jest.genMockFromModule(moduleName)
与えられた名前のモジュールに対して自動モック化システムを利用してモック化したモジュールを作成します。
自動モックが持つ機能を拡張した マニュアルモックを作成したい場合に便利です。
例:
// utils.js
export default {
authorize: () => {
return 'token';
},
isAuthorized: secret => secret === 'wizard',
};
// __tests__/genMockFromModule.test.js
const utils = jest.genMockFromModule('../utils').default;
utils.isAuthorized = jest.fn(secret => secret === 'not wizard');
test('implementation created by jest.genMockFromModule', () => {
expect(utils.authorize.mock).toBeTruthy();
expect(utils.isAuthorized('not wizard')).toEqual(true);
});
This is how genMockFromModule
will mock the following data types:
関数
Creates a new mock function. The new function has no formal parameters and when called will return undefined
. This functionality also applies to async
functions.
クラス
Creates a new class. The interface of the original class is maintained, all of the class member functions and properties will be mocked.
オブジェクト
Creates a new deeply cloned object. The object keys are maintained and their values are mocked.
Creates a new empty array, ignoring the original.
プリミティブ型
Creates a new property with the same primitive value as the original property.
例:
// example.js
module.exports = {
function: function square(a, b) {
return a * b;
},
asyncFunction: async function asyncSquare(a, b) {
const result = await a * b;
return result;
},
class: new class Bar {
constructor() {
this.array = [1, 2, 3];
}
foo() {}
},
object: {
baz: 'foo',
bar: {
fiz: 1,
buzz: [1, 2, 3],
},
},
array: [1, 2, 3],
number: 123,
string: 'baz',
boolean: true,
symbol: Symbol.for('a.b.c'),
};
// __tests__/example.test.js
const example = jest.genMockFromModule('./example');
test('should run example code', () => {
// creates a new mocked function with no formal arguments.
expect(example.function.name).toEqual('square');
expect(example.function.length).toEqual(0);
// async functions get the same treatment as standard synchronous functions.
expect(example.asyncFunction.name).toEqual('asyncSquare');
expect(example.asyncFunction.length).toEqual(0);
// creates a new class with the same interface, member functions and properties are mocked.
expect(example.class.constructor.name).toEqual('Bar');
expect(example.class.foo.name).toEqual('foo');
expect(example.class.array.length).toEqual(0);
// creates a deeply cloned version of the original object.
expect(example.object).toEqual({
baz: 'foo',
bar: {
fiz: 1,
buzz: [],
},
});
// creates a new empty array, ignoring the original array.
expect(example.array.length).toEqual(0);
// creates a new property with the same primitive value as the original property.
expect(example.number).toEqual(123);
expect(example.string).toEqual('baz');
expect(example.boolean).toEqual(true);
expect(example.symbol).toEqual(Symbol.for('a.b.c'));
});
jest.mock(moduleName, factory, options)
Mocks a module with an auto-mocked version when it is being required. factory
and options
are optional. 例:
// banana.js
module.exports = () => 'banana';
// __tests__/test.js
jest.mock('../banana');
const banana = require('../banana'); // banana will be explicitly mocked.
banana(); // will return 'undefined' because the function is auto-mocked.
第2引数はJestの自動モックによる設定を用いる代わりに明示的にモジュールのファクトリを指定する場合に使用します。
jest.mock('../moduleName', () => {
return jest.fn(() => 42);
});
// This runs the function specified as second argument to `jest.mock`.
const moduleName = require('../moduleName');
moduleName(); // Will return '42';
デフォルトのエクスポートのES6モジュールで factory
パラメータを使用する場合、 __esModule: true
プロパティを指定する必要があります。 通常、このプロパティは Babel / TypeScript によって生成されますが、ここでは手動で設定する必要があります。 デフォルトエクスポートをインポートする場合、エクスポートオブジェクトから default
という名前のプロパティをインポートします。
import moduleName, {foo} from '../moduleName';
jest.mock('../moduleName', () => {
return {
__esModule: true,
default: jest.fn(() => 42),
foo: jest.fn(() => 43),
};
});
moduleName(); // 42を返します
foo(); // 43を返します
第3引数は仮想モックを作成するのに使用します - これはシステム内のどこにも存在しないモジュールのモックです。
jest.mock(
'../moduleName',
() => {
/*
* Custom implementation of a module that doesn't exist in JS,
* like a generated module or a native module in react-native.
*/
},
{virtual: true},
);
Warning: Importing a module in a setup file (as specified by
setupTestFrameworkScriptFile
) will prevent mocking for the module in question, as well as all the modules that it imports.
jest.mock
によりモックされるモジュールは、jest.mock
を呼び出したファイル内でのみモックされます。 モジュールをモックしたテストの後に実行したとしても、そのモジュールをインポートする別のファイルでは、本物のモジュールがインポートされます。
メソッドチェーンのためにjest
オブジェクトを返します。
jest.unmock(moduleName)
指定したモジュールについてrequire()
した際に、モジュールシステムは決してモックしたものを返さないことを設定します(例えば常に本物のモジュールを返すべき場合など)。
このAPIの最も一般的な用途は、指定されたモジュールを与えられたテストファイルでテストしようとしている場合(そのため自動的にモックをしたくない場合) です。
メソッドチェーンのためにjest
オブジェクトを返します。
jest.doMock(moduleName, factory, options)
When using babel-jest
, calls to mock
will automatically be hoisted to the top of the code block. Use this method if you want to explicitly avoid this behavior.
この関数が有用な例の1つとして、同一ファイル内で異なる振る舞いのモックを使用したい場合が挙げられます:
beforeEach(() => {
jest.resetModules();
});
test('moduleName 1', () => {
jest.doMock('../moduleName', () => {
return jest.fn(() => 1);
});
const moduleName = require('../moduleName');
expect(moduleName()).toEqual(1);
});
test('moduleName 2', () => {
jest.doMock('../moduleName', () => {
return jest.fn(() => 2);
});
const moduleName = require('../moduleName');
expect(moduleName()).toEqual(2);
});
Using jest.doMock()
with ES6 imports requires additional steps. Follow these if you don't want to use require
in your tests:
__esModule: true
プロパティを指定する必要があります (詳細についてはjest.mock()
API を参照してください)。- 静的ES6モジュールのインポートはファイルの先頭で行われてしまうので、代わりに
import()
を使用して動的にインポートする必要があります。 - 最後に、動的インポートをサポートする環境が必要です。 初期設定については、 Using Babel を参照してください。 次に、プラグイン babel-plugin-dynamic-import-node、または同等のものを Babel の設定に追加して、Node での動的インポートを有効にします。
beforeEach(() => {
jest.resetModules();
});
test('moduleName 1', () => {
jest.doMock('../moduleName', () => {
return {
__esModule: true,
default: 'default1',
foo: 'foo1',
};
});
return import('../moduleName').then(moduleName => {
expect(moduleName.default).toEqual('default1');
expect(moduleName.foo).toEqual('foo1');
});
});
test('moduleName 2', () => {
jest.doMock('../moduleName', () => {
return {
__esModule: true,
default: 'default2',
foo: 'foo2',
};
});
return import('../moduleName').then(moduleName => {
expect(moduleName.default).toEqual('default2');
expect(moduleName.foo).toEqual('foo2');
});
});
メソッドチェーンのためにjest
オブジェクトを返します。
jest.dontMock(moduleName)
When using babel-jest
, calls to unmock
will automatically be hoisted to the top of the code block. Use this method if you want to explicitly avoid this behavior.
メソッドチェーンのためにjest
オブジェクトを返します。
jest.setMock(moduleName, moduleExports)
指定されたモジュールについてモジュールシステムが返すべきモックオブジェクトを明示的に与えます。
On occasion, there are times where the automatically generated mock the module system would normally provide you isn't adequate enough for your testing needs. 通常そのような状況では当該のモジュールにより適したマニュアルモックを作成するべきです。 しかしとても稀ですが、マニュアルモックですら目的に対して適切でなくテスト内でモックを作成する必要があるケースがあります。
これらの稀なシナリオでは、このAPIでモジュールシステムのモックモジュールのレジストリのスロットに手動で設定することができます。
メソッドチェーンのためにjest
オブジェクトを返します。
注意: このAPIの代わりにjest.mock()
を利用することをお勧めします。 jest.mock
APIの第2引数はエクスポートされたモジュールのオブジェクトの代替となるモジュールのファクトリを指定できます。
jest.requireActual(moduleName)
モジュールがモックしたものを受け取る設定であるかを確認せず、モックではない本物のモジュールを返すようになります。
例:
jest.mock('../myModule', () => {
// Require the original module to not be mocked...
const originalModule = jest.requireActual('../myModule');
return {
__esModule: true, // Use it when dealing with esModules
...originalModule,
getRandom: jest.fn().mockReturnValue(10),
};
});
const getRandom = require('../myModule').getRandom;
getRandom(); // Always returns 10
jest.requireMock(moduleName)
モジュールが通常通りrequireされるかを確認せず、本物のモジュールではないモックを返すようになります。
jest.resetModules()
Resets the module registry - the cache of all required modules. This is useful to isolate modules where local state might conflict between tests.
例:
const sum1 = require('../sum');
jest.resetModules();
const sum2 = require('../sum');
sum1 === sum2;
// > false (Both sum modules are separate "instances" of the sum module.)
テストにおける例:
beforeEach(() => {
jest.resetModules();
});
test('works', () => {
const sum = require('../sum');
});
test('works too', () => {
const sum = require('../sum');
// sum is a different copy of the sum module from the previous test.
});
メソッドチェーンのためにjest
オブジェクトを返します。
jest.isolateModules(fn)
jest.isolateModules(fn)
goes a step further than jest.resetModules()
and creates a sandbox registry for the modules that are loaded inside the callback function. This is useful to isolate specific modules for every test so that local module state doesn't conflict between tests.
let myModule;
jest.isolateModules(() => {
myModule = require('myModule');
});
const otherCopyOfMyModule = require('myModule');
モック関数
jest.fn(implementation)
新しい、未使用の mock function を返します。 必要に応じてモック実装を設定します。
const mockFn = jest.fn();
mockFn();
expect(mockFn).toHaveBeenCalled();
// With a mock implementation:
const returnsTrue = jest.fn(() => true);
console.log(returnsTrue()); // true;
jest.isMockFunction(fn)
与えられた関数がモック関数がどうかを返します。
jest.spyOn(object, methodName)
Creates a mock function similar to jest.fn
but also tracks calls to object[methodName]
. Jestの モック関数 を返します。
注意: デフォルトでは、 jest.spyOn
はスパイ化されたメソッドも呼び出します。 これは他の大抵のテストライブラリとは異なる振る舞いです。 元の関数を上書きしたい場合は、 jest.spyOn(object, methodName).mockImplementation(() => customImplementation)
または object[methodName] = jest.fn(() => customImplementation);
を使用して下さい。
例:
const video = {
play() {
return true;
},
};
module.exports = video;
テストの例:
const video = require('./video');
test('plays video', () => {
const spy = jest.spyOn(video, 'play');
const isPlaying = video.play();
expect(spy).toHaveBeenCalled();
expect(isPlaying).toBe(true);
spy.mockRestore();
});
jest.spyOn(object, methodName, accessType?)
Jest 22.1.0+ からは jest.spyOn
メソッドはオプションの第3引数 accessType
を取るようになりました。この引数には 'get'
または 'set'
を指定することができ、それぞれゲッタやセッタをスパイしたい場合に便利です。
例:
const video = {
// it's a getter!
get play() {
return true;
},
};
module.exports = video;
const audio = {
_volume: false,
// it's a setter!
set volume(value) {
this._volume = value;
},
get volume() {
return this._volume;
},
};
module.exports = audio;
テストの例:
const audio = require('./audio');
const video = require('./video');
test('plays video', () => {
const spy = jest.spyOn(video, 'play', 'get'); // we pass 'get'
const isPlaying = video.play;
expect(spy).toHaveBeenCalled();
expect(isPlaying).toBe(true);
spy.mockRestore();
});
test('plays audio', () => {
const spy = jest.spyOn(audio, 'volume', 'set'); // we pass 'set'
audio.volume = 100;
expect(spy).toHaveBeenCalled();
expect(audio.volume).toBe(100);
spy.mockRestore();
});
jest.clearAllMocks()
Clears the mock.calls
and mock.instances
properties of all mocks. Equivalent to calling .mockClear()
on every mocked function.
メソッドチェーンのためにjest
オブジェクトを返します。
jest.resetAllMocks()
Resets the state of all mocks. Equivalent to calling .mockReset()
on every mocked function.
メソッドチェーンのためにjest
オブジェクトを返します。
jest.restoreAllMocks()
全てのモックを初期値に戻します。 Equivalent to calling .mockRestore()
on every mocked function. Beware that jest.restoreAllMocks()
only works when the mock was created with jest.spyOn
; other mocks will require you to manually restore them.
モックタイマー
jest.useFakeTimers()
Jestに標準タイマー関数の偽のバージョンを使うように指示します (setTimeout
, setInterval
, clearTimeout
, clearInterval
, nextTick
, setImmediate
そして clearImmediate
が対象の関数です)。
メソッドチェーンのためにjest
オブジェクトを返します。
jest.useRealTimers()
Jestに標準タイマー関数の実際のバージョンを使用するように指示します。
メソッドチェーンのためにjest
オブジェクトを返します。
jest.runAllTicks()
micro-task キューを処理します(通常はnodeでprocess.nextTick
経由でやり取りします)。
このAPIが呼ばれた場合、process.nextTick
経由でキューイングされた全ての保留中のmicro-taskが実行されます。 さらに、それらmicro-task自身が新しいmicro-taskをスケジュールしている場合は、キューからmicro-taskが無くなるまで継続的に処理されます。
jest.runAllTimers()
Exhausts both the macro-task queue (i.e., all tasks queued by setTimeout()
, setInterval()
, and setImmediate()
) and the micro-task queue (usually interfaced in node via process.nextTick
).
When this API is called, all pending macro-tasks and micro-tasks will be executed. If those tasks themselves schedule new tasks, those will be continually exhausted until there are no more tasks remaining in the queue.
このAPIは setTimeout()
や setInterval()
コールバックが実行された後でのみ発生するような動作を同期して確認するために、テスト中に同期的にsetTimeouts関数を動作させる場合に便利です。 詳細については Timer mocks ドキュメントを参照してください。
jest.runAllImmediates()
setImmediate()
によってキューイングされた全てのタスクを処理します。
jest.advanceTimersByTime(msToRun)
jest バージョン 22.0.0以上 で改名
次の別名でも同様となります: .runTimersToTime()
macro taskキューのみを実行します(つまり、 setTimeout()
か setInterval()
や setImmediate()
によってキューイングされた全てのタスクです)。
この API が呼び出されると、すべてのタイマーは msToRun
ミリ秒で進みます。 このタイムフレームで実行されるであろう、全ての setTimeout()
または setInterval()
経由でキューイングされた保留中の "macro-tasks" が実行されます。 Additionally, if those macro-tasks schedule new macro-tasks that would be executed within the same time frame, those will be executed until there are no more macro-tasks remaining in the queue, that should be run within msToRun
milliseconds.
jest.runOnlyPendingTimers()
現時点で保留中のmacro-taskのみを実行します(つまりこの時点までにsetTimeout()
か setInterval()
によってキューイングされたタスクのみです)。 その時点で保留中の macro-tasksが新しい macro-taskをスケジュールしている場合、それらの新しいタスクはこのAPIからの呼び出しでは実行されません。
このAPIはテスト対象のモジュールがsetTimeout()
が新たなsetTimeout()
をコールバック内で再帰的にスケジュールしているようなシナリオに役立ちます(コールバック内のスケジューリングは停止しないということです) これらのシナリオでは、一度に1回ずつ時間を進めることができる事が便利なのです。
jest.advanceTimersToNextTimer(steps)
Advances all timers by the needed milliseconds so that only the next timeouts/intervals will run.
Optionally, you can provide steps
, so it will run steps
amount of next timeouts/intervals.
jest.clearAllTimers()
タイマーシステムが保留しているあらゆるタイマーを削除します。
つまり、(まだ実行されていない) スケジュールされた全てのタイマーについて、削除され、将来にわたって実行されることはないという事です。
jest.getTimerCount()
Returns the number of fake timers still left to run.
その他
jest.setTimeout(timeout)
テストと前後のフックスクリプトでデフォルト値となるタイムアウト間隔をミリ秒単位で設定します。 This only affects the test file from which this function is called.
注意: このメソッドが呼ばれなかった場合、デフォルトのタイムアウト間隔は5秒です。
Note: If you want to set the timeout for all test files, a good place to do this is in setupFilesAfterEnv
.
例:
jest.setTimeout(1000); // 1 second
jest.retryTimes()
Runs failed tests n-times until they pass or until the max number of retries is exhausted. This only works with jest-circus!
テストにおける例:
jest.retryTimes(3);
test('will fail', () => {
expect(true).toBe(false);
});
メソッドチェーンのためにjest
オブジェクトを返します。