Jest Object API Reference
Today we will take a look at the Jest object, then we will study the modules that the methods in the Jest object helps us to create.
Jest Object
Within every test file written in Jest, the jest object is in scope automatically. The methods in jest object enable us to create mocks and helps us to control Jest?s overall behavior.
Mock Modules
jest.disableAutomock()
This will disable mocking in the module loader. Once this method is called, all require() s returns the real version for each module (instead of a mocked version).
{
"automock": true
}```
For instance:
// utils.js
```export default {
authorize: () => {
return 'token';
},
};
// __tests__/disableAutomocking.js
```import utils from '../utils';
jest.disableAutomock();
test('original implementation', () => {
// we now have the original implementation,
// even when we set the automocking in a jest configuration
expect(utils.authorize()).toBe('token');
});
Usually, this is useful when you have a scenario where the number of dependencies you want to mock is far less than the number of dependencies that you don?t. for instance, when you are writing a test for a module that will use a large number of dependencies that can reasonably be classified as ?implementation details? of the module, you most likely do not want to mock them.
Examples of dependencies that could be considered ?implementation details? are things that range from language built-in (e.g Array.prototype methods) to the highly common utility methods ( like underscore/lo-dash, array utilities etc) and entire libraries such as React.js.
jest.disableAutomock() returns jest object for chaining.
Note: jest.disableAutomock() method was previously called autoMockOff. When you are using babel-jest, calls to disableAutomock are automatically hoisted to the top of the code block. Use autoMockOff when you want to explicitly avoid this behavior.
jest.enableAutomock()
This method enables automatic mocking in the module loader. It returns the jest object for chaining.
Example:
// utils.js
export default {
authorize: () => {
return 'token';
},
isAuthorized: secret => secret === 'wizard',
};
// __tests__/disableAutomocking.js
```jest.enableAutomock();
import utils from '../utils';
test('original implementation', () => {
// we have now the mocked implementation,
expect(utils.authorize._isMockFunction).toBeTruthy();
expect(utils.isAuthorized._isMockFunction).toBeTruthy();
});
Note: jest.enableAutomock() method was previously called autoMockOn. When you are using babel-jest, calls to enableeAutomock are automatically hoisted to the top of the code block. Use autoMockOn when you want to explicitly avoid this behavior.
jest.genMockFromModule(moduleName)
When you are given the name of a module, you should use the automatic mocking system to generate a mocked version of the module for you.
This is useful if you want to create a manual mock that will extend the automatic mock?s behavior.
Example:
// 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 that is created by jest.genMockFromModule', () => {
expect(utils.authorize.mock).toBeTruthy();
expect(utils.isAuthorized('not wizard')).toEqual(true);
});
This is how genMockFromModule mocks the following data:
Function
It will create a new mock function. The new function will have no formal parameters and when called returns undefined. This functionality will also apply to async functions.
Class
It will create new class. The interface of the original class will be maintained, all of the class member functions and properties are mocked.
Object
Will create a new deeply cloned object. The object keys will be maintained and their values will be mocked.
Array
Will create a new empty array, ignoring the original.
Primitives
Will create a new property with the same primitive value as the original property.
Example:
// 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('this should run example code', () => {
// this will create a new mocked function with no formal arguments.
expect(example.function.name).toEqual('square');
expect(example.function.length).toEqual(0);
// async functions will get the same treatment as standard synchronous functions.
expect(example.asyncFunction.name).toEqual('asyncSquare');
expect(example.asyncFunction.length).toEqual(0);
// will create 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);
// will create a deeply cloned version of the original object.
expect(example.object).toEqual({
baz: 'foo',
bar: {
fiz: 1,
buzz: [],
},
});
// this will create a new empty array, ignoring the original array.
expect(example.array.length).toEqual(0);
// this will 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)
This will mock a module with an auto-mocked version when it is being required. options and factory are optional. For instance:
// orange.js
```module.exports = () => 'orange';```
// __tests__/test.js
```jest.mock('../orange');
const banana = require('../orange'); // orange is explicitly mocked.
orange(); // will return 'undefined' because the function is auto-mocked.```
the second argument can be used to specify an explicit module factory that being run rather than using Jest?s auto-mocking feature:
```jest.mock('../moduleName', () => {
return jest.fn(() => 42);
});
// This will run the function specified as second argument to `jest.mock`.
const moduleName = require('../moduleName');
moduleName(); // Will return '42';
When you are using the factory parameter for an ES6 module with a default export, the __esModule: true property has to be specified. This property will normally be generated by Babel / TypeScript, but here it has to be set manually. When you are importing a default export, it's an instruction to import the property named default from the export object:
import moduleName, {foo} from '../moduleName';
jest.mock('../moduleName', () => {
return {
__esModule: true,
default: jest.fn(() => 52),
foo: jest.fn(() => 53),
};
});
moduleName(); // Will return 52
foo(); // Will return 53
You can use the third argument to create virtual mocks- these are mocks that don?t exist anywhere in the system:
jest.mock(
'../moduleName',
() => {
/*
* Custom implementation of a module that does not exist in JS,
* such as a generated module or a native module in react-native.
*/
},
{virtual: true},
);
Modules that are mocked using jest.mock are mocked only for the file that will call jest.mock. Another file that imports the module gets the original implementation even if it runs after the test file that mocks the module. This method returns the jest object for chaining.
jest.unmock(moduleName)
This method indicates that the module system should never return a mocked version of the specified module from require() (e.g. it should always return the real module).
The most common use of this API is to specify the module a given test intends to be testing (and thus doesn't want automatically mocked). It will return the jest object for chaining.
jest.doMock(moduleName, factory, options)
When you are using babel-jest, calls to mock are automatically hoisted to the top of the code block. You should use this method if you want to explicitly avoid this behavior.
An example when this is useful is when you want to mock a module differently within the same file:
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 demands additional steps. You should follow these if you don't want to use require in your tests:
- You have to specify the __esModule: true property.
- Static ES6 module imports will be hoisted to the top of the file, so instead you have to use import() to import them dynamically.
- Finally, you need an environment which supports dynamic importing. Please see the babel section of our getting started with Jest for the initial setup. Then you should add the plugin babel-plugin-dynamic-import-node, or an equivalent, inside your Babel config to enable dynamic importing in 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');
});
});
This will return the jest object for chaining.
jest.dontMock(moduleName)
When you are using babel-jest, calls to unmock are automatically hoisted to the top of the code block. So, you should use this method if you want to explicitly avoid this behavior. This method returns the jest object for chaining.
jest.setMock(moduleName, moduleExports)
This explicitly supplies the mock object that the module system should return for the specified module.
Occasionally, there are times where the automatically generated mock that the module system would normally provide you isn't adequate enough for your testing needs. In those circumstances you should write a manual mock that is more adequate for the module in question. There are however, some extreme cases where even a manual mock isn't suitable for your purposes and you need to build the mock yourself inside the test.
In such rare scenarios you can use jest.setMock(moduleName, moduleExports) to manually fill the slot in the module system's mock-module registry. It returns the jest object for chaining.
Note: We recommend that you to use jest.mock() instead. The jest.mock API's second argument is a module factory rather than the expected exported module object.
jest.requireActual(moduleName)
This returns the actual module instead of a mock, it bypasses all checks on whether the module should receive a mock implementation or not.
Example:
jest.mock('../myModule', () => {
// Requires the original module to not be mocked...
const originalModule = jest.requireActual(moduleName);
return {
__esModule: true, // you should use it when dealing with esModules
...originalModule,
getRandom: jest.fn().mockReturnValue(10),
};
});
const getRandom = require('../myModule').getRandom;
getRandom(); // will always return 10
jest.requireMock(moduleName)
This will return a mock module instead of the actual module, it bypasses all checks on whether the module should be required normally or not.
jest.resetModules()
This will reset the module registry - the cache of all required modules. It is useful to isolate modules where local state might conflict between tests.
Example:
const sum1 = require('../sum');
jest.resetModules();
const sum2 = require('../sum');
sum1 === sum2;
// > false (Both sum modules will be separate "instances" of the sum module.)
An example in a test is as shown:
beforeEach(() => {
jest.resetModules();
});
test('works', () => {
const sum = require('../sum');
});
test('works too', () => {
const sum = require('../sum');
// sum here is a different copy of the sum module from the previous test.
});
This will return the jest object for chaining.
jest.isolateModules(fn)
The jest.isolateModules(fn) method goes a step further than jest.resetModules() and creates a sandbox registry for the modules which are loaded inside the callback function. This method 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');
Mock functions
jest.fn(implementation)
This will return a new, unused mock function. This will optionally take a mock implementation.
const mockFn = jest.fn();
mockFn();
expect(mockFn).toHaveBeenCalled();
// With a mock implementation:
const returnsTrue = jest.fn(() => true);
console.log(returnsTrue()); // true;
jest.isMockFunction(fn)
This will determine if the given function is a mocked function.
jest.spyOn(object, methodName)
This will create a mock function that similar to jest.fn but also tracks calls to object[methodName]. It will return a Jest mock function.
Note: By default, jest.spyOn will also call the spied method. This behavior is different from the behavior of most other test libraries. If you would like to overwrite the original function, use jest.spyOn(object, methodName).mockImplementation(() => customImplementation) or object[methodName] = jest.fn(() => customImplementation);
Example:
const video = {
play() {
return true;
},
};
module.exports = video;```
Example test:
```const video = require('./video');
test('will play 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?)
From Jest version 22.1.0+, the jest.spyOn method will take an optional third argument of accessType which can be either 'get' or 'set', which will prove to be useful when you want to spy on a getter or a setter, respectively.
Example:
const video = {
// it is a getter!
get play() {
return true;
},
};
module.exports = video;
const audio = {
_volume: false,
// it is a setter!
set volume(value) {
this._volume = value;
},
get volume() {
return this._volume;
},
};
module.exports = audio;
Example test:
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();
});
const audio = require('./audio');
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()
This will clear the mock.calls and mock.instances properties of all mocks. This is equivalent to calling .mockClear() on every mocked function. It will return the jest object for chaining.
jest.resetAllMocks()
This will reset the state of all mocks. It is equivalent to calling .mockReset() on every mocked function. It will return the jest object for chaining.
jest.restoreAllMocks()
This will restore all mocks back to their original value. It is equivalent to calling .mockRestore() on every mocked function. Beware that jest.restoreAllMocks() will only work when the mock was created using jest.spyOn; other mocks require you to manually restore them.
Mock timers
jest.useFakeTimers()
This will instruct Jest to use fake versions of the standard timer functions (setTimeout, setInterval, clearTimeout, clearInterval, nextTick, setImmediate and clearImmediate). It will return the jest object for chaining.
jest.useRealTimers()
This will instruct Jest to use the real versions of the standard timer functions. It will return the jest object for chaining.
jest.runAllTicks()
This will exhaust the micro-task queue (which is usually interfaced in node via process.nextTick)
If this API is called, all pending micro-tasks which have been queued via process.nextTick are executed. Additionally, in the case where those micro-tasks themselves schedule new micro-tasks, they are continually exhausted until there are no more micro-tasks remaining in the queue.
jest.runAllTimers()
It will exhaust both the macro-task queue (i.e., all tasks queued by setTimeout(), setInterval(), and setImmediate()) and the micro-task queue (which are usually interfaced in node via process.nextTick).
When you call this API, all the pending macro-tasks and micro-tasks are executed. In the case where those tasks themselves schedule new tasks, they are continually exhausted until there are no more tasks remaining in the queue.
This is useful for synchronously executing setTimeouts during a test so as to synchronously assert about some behavior that would only happen after the setTimeout() or setInterval() callbacks executed.
jest.runAllImmediates()
This will exhaust all tasks queued by setImmediate().
jest.advanceTimersByTime(msToRun)
jest.advanceTimersByTime has been renamed in Jest 22.0.0+
It is also under the alias: .runTimersToTime()
This will execute only the macro task queue (i.e. all tasks queued by setTimeout() or setInterval() and setImmediate()).
When you call this API, all timers will be advanced by msToRun milliseconds. All pending "macro-tasks" which have been queued via setTimeout() or setInterval(), and would be executed within this time frame are executed. Additionally, in the case where those macro-tasks schedule new macro-tasks that would be executed within the same time frame, they will be executed until there are no more macro-tasks remaining in the queue, that is to be run within msToRun milliseconds.
jest.runOnlyPendingTimers()
This executes only the macro-tasks that are currently pending (i.e., only the tasks which were queued by setTimeout() or setInterval() up to this point). In the case where any of the currently pending macro-tasks schedule new macro-tasks, those new tasks will not be executed by this call.
This is very useful for scenarios such as one where the module being tested schedules a setTimeout() whose callback schedules another setTimeout() recursively (meaning the scheduling is infinite). In such scenarios, it will be useful to be able to run forward in time by a single step at a time.
jest.advanceTimersToNextTimer(steps)
This will advance all timers by the needed milliseconds so that only the next timeouts/intervals will run.
You can optionally provide steps, so it runs steps amount of next timeouts/intervals.
jest.clearAllTimers()
This will remove any pending timers from the timer system.
What this means is that, in the case where any timers have been scheduled (but have not yet executed), they are cleared and are never have the opportunity to execute in the future.
jest.getTimerCount()
This will return the number of fake timers still left to run.
Misc
jest.setTimeout(timeout)
This will set the default timeout interval for tests and before/after hooks in milliseconds.
Note: 5 seconds is the default timeout if this method is not called.
Note: In the case where you want to set the timeout for all test files, setupFilesAfterEnv is a good place to do that.
Example:
jest.setTimeout(1000); // 1 second
jest.retryTimes()
This will run failed tests n-times until they pass or you have exhausted the max number of retries. This will only work with jest-circus!
A test Example:
jest.retryTimes(3);
test('will fail', () => {
expect(true).toBe(false);
});
This will return the jest object for chaining.
Previous:
Jest Mock Functions API Reference.
Next:
Configuring Jest: Setup Options and Customization.
It will be nice if you may share this link in any developer community or anywhere else, from where other developers may find this content. Thanks.
https://w3resource.com/jest/jest-object.php
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics