The Mock related API

There are three apis related to Mock functions in Jest: jest.fn(), jest.spyon (), and jest.mock(). Using them to create Mock functions can help you better test logically complex code in your project, such as nested calls to test functions, callbacks, etc.

Mock functions provide the following three features:

  • 1. Capture function calls
  • 2. Set the function return value
  • 3. Change the internal implementation of functions

jest.fn()

Jest.fn () is the easiest way to create Mock functions, and if the internal implementation of the function is not defined, jest.fn() returns undefined as the return value.

test('Test the jest. Fn () call', () = > {let mockFn = jest.fn();
  letresult = mockFn(1, 2, 3); // assert that mockFn returns undefined expect(result).tobeundefined (); // Assert that mockFn is called expect(mockFn).tobecalled (); // assert that mockFn is called once Expect (mockFn).tobecalledTimes (1); // Expect (mockFn).tohaveBeencalledwith (1, 2, 3); })Copy the code

The Mock function created by jest.fn() can also set return values, define internal implementations, or return Promise objects.

// functions.test.js

test('Test jest.fn() returns fixed value', () = > {let mockFn = jest.fn().mockReturnValue('default'); // assert that mockFn returns default expect(mockFn()).tobe ('default');
})

test('Test the internal implementation of jest.fn()', () = > {let mockFn = jest.fn((num1, num2) => {
    returnnum1 * num2; }) // return 100 expect(mockFn(10, 10)).tobe (100); })test('Test jest.fn() returns Promise', async () => {
  let mockFn = jest.fn().mockResolvedValue('default');
  letresult = await mockFn(); // assert mockFn returns default expect(result).tobe () after execution with await keyword'default'); / / assertion mockFn call returns after Promise Object expect (Object. The prototype. ToString. Call (mockFn ())). The place ("[object Promise]");
})
Copy the code

jest.mock()

A wrapped request method may not need to make the actual request when another module is called (the request method has already passed a single test or requires the method to return non-real data). At this point, it is necessary to mock the entire module using jest. Mock ().

// fetch.js

import axios from 'axios';

export default {
  async fetchPostsList(callback) {
    return axios.get('https://jsonplaceholder.typicode.com/posts').then(res => {
      returncallback(res.data); }}})Copy the code
// events.js
import fetch from './fetch';

export default {
  async getPostList() {
    return fetch.fetchPostsList(data => {
      console.log('fetchPostsList be called! '); }); }}Copy the code
// functions.test.js

import events from '.. /src/events';
import fetch from '.. /src/fetch';

jest.mock('.. /src/fetch.js');

test('Mock the whole fetch. Js module', async () => {
  expect.assertions(2);
  await events.getPostList();
  expect(fetch.fetchPostsList).toHaveBeenCalled();
  expect(fetch.fetchPostsList).toHaveBeenCalledTimes(1);
});
Copy the code

In Jest, if you want to catch a function being called, the function must be mock or spy

jest.spyOn()

The jest.spyon () method also creates a mock function, but the mock function not only captures the function invocation, but also executes the spy function normally. In fact, jest.spyon () is the syntactic sugar of jest.fn(), which creates a mock function with the same internal code as the spy function.

console.log(‘fetchPostsList be called! ‘); This line of code is not printed because methods inside the module are not actually executed by Jest after passing jest. Mock (). This is where we need to use jest. SpyOn ().

// functions.test.js

import events from '.. /src/events';
import fetch from '.. /src/fetch';

test('Use jest.spyon () to monitor that fetch. FetchPostsList is called properly', async() => {
  expect.assertions(2);
  const spyFn = jest.spyOn(fetch, 'fetchPostsList');
  await events.getPostList();
  expect(spyFn).toHaveBeenCalled();
  expect(spyFn).toHaveBeenCalledTimes(1);
})

Copy the code

conclusion

In real project unit tests, jest.fn() is often used for some tests with callback functions; Jest. Mock () can mock methods in an entire module. When a module is 100% covered by a unit test, using jest. Mock () is necessary to save test time and redundancy. Jest. SpyOn () is often used when you need to test some method that must be executed in its entirety. All of these need to be flexibly chosen by the developer based on the actual business code.