Preparation conditions

Build on the directories and code created in the tutorial in Section 1. If you haven’t seen the first tutorial, follow me for previous articles in this series

This tutorial focuses on the mock functions in Jest. Make a copy of the code in Section 1 and add the mock functionsindex.jsandindex.test.jsDelete all files

Mock functions can be used to capture calls to functions, parameters, and return values as you test your actual code, or to simulate data

Install axios

  • npm run axios --save

Write some methods to be tested in index.js

import axios from 'axios'

export function callbackFun(fn) {
  return fn()
}

export function getData() {
  // Write an arbitrary interface path
  return axios.get('/api').then(res= > res.data)
}
Copy the code

Use the mock

Write a test instance to index.test.js

import { callbackFun, getData } from './index'

test('Test callbackFun, set return value using mockReturnValueOnce', () = > {let fun = jest.fn()
  fun.mockReturnValueOnce('123') // Sets the return value of calling the function once
  fun.mockReturnValueOnce('456') // Sets the return value of calling the function twice
  fun.mockReturnValue('666') // Set the value of each call to 666
  
  expect(callbackFun(fun)).toBe('123')
  expect(callbackFun(fun)).toBe('456')
  expect(callbackFun(fun)).toBe('666')
  expect(callbackFun(fun)).toBe('666')

  console.log(fun.mock)
})
Copy the code
  • herejest.fn()Here jEST is used to simulate a function, and you can pass in a function to generate a function with logic
  • .mockReturnValueOnce()Set the return value of a function called once, or several times
  • .mockReturnValue()Sets the return value of the calling function
  • .mockEach jEST-generated function has mock properties that contain the following properties

Write one more test instance in index.test.js

test('Test callbackFun, set return value using mockImplementation', () = > {let fun = jest.fn()

  // Sets the return value of calling the function once
  fun.mockImplementationOnce((a)= > {
    return '123'
  })

  // Set the value of each call to 666
  fun.mockImplementation((a)= > {
    return '666'
  })

  expect(callbackFun(fun)).toBe('123')
  expect(callbackFun(fun)).toBe('666')
  expect(callbackFun(fun)).toBe('666')})Copy the code
  • Here,mockImplementationOncemockReturnValueOnceSet the return value of the function once, but with more power, you can write more logic inside the function
  • mockImplementationmockReturnValueThe function is the same, set the return value of each function, more powerful

There is a mock attribute in jest.fn() that you can use to make things happen

Write one more test instance in index.test.js

test('Test callbackFun, test with mock property', () = > {let fun = jest.fn()

  fun.mockReturnValueOnce('123')
  fun.mockReturnValue('666')

  let obj = {}
  callbackFun(fun.bind(obj))
  callbackFun(fun)

  expect(fun).toBeCalled() // Tests whether fun is called
  expect(fun.mock.calls.length).toBe(2) // Tests whether the function is called twice
  expect(fun.mock.instances[0]).toEqual(obj) // Test if the first call to this is obj
  expect(fun.mock.calls[0] [0]).toBeUndefined()  // Tests whether the argument of the first call to the function is null
  console.log(fun.mock)
})
Copy the code

Here you can print a mock to understand

Mock the interface data

In a real development project, we can’t test the interface directly; the best way to test the interface is to mock it

// These two sentences are added to the test file header
import axios from 'axios'
jest.mock('axios')

test('Test getData, use mock'.async() = > {// Simulate the first received data
  axios.get.mockResolvedValueOnce({
    data: '123'
  })
  // Simulate each received data
  axios.get.mockResolvedValue({
    data: '456'
  })

  const data1 = await getData()
  const data2 = await getData()
  expect(data1).toBe('123')
  expect(data2).toBe('456')})Copy the code
  • jest.mock('axios')Mimicking the AXIos request for data, not sending a real request (changing the internal implementation of the AXIos function) so that we don’t actually request the backend interface data, but instead use our own data structure

The simulated asynchronous data code is presented

This solved the problem, but we wanted to write code more elegantly, and it was always not good to write simulated data in test instances, so JEST also gave us another way

  • willindex.test.jsContent to delete
  • Root Directory Creation__mocks__Folder, create a new folder insideindex.jsAnd write the following content
// Return a promise
export function getData() {
  return new Promise(resolve= > {
    resolve({
      data: 'Test data'})})}Copy the code
  • inindex.test.jsWrite the following test case to
jest.mock('./index') // Set up to use mock files
import { getData } from './index' // look in the __mocks__ folder

// Set the callbackFun method to look up from the source file index
const { callbackFun } = jest.requireActual('./index')


test('Test getData, use __mock__'.async() = > {const data = await getData()
  expect(data).toEqual({ data: 'Test data' })
})

test('Test callbackFun, set return value using mockReturnValueOnce', () = > {let fun = jest.fn()
  fun.mockReturnValueOnce('123') 
  
  expect(callbackFun(fun)).toBe('123')})Copy the code

Now that we’ve successfully taken asynchronous data out, there are a few things to note here

  • jest.mock('./index')Automatically find files from the __mocks__ file
  • When set, the file import takes is in __mocks__, but we need to test other methods, so we need to set itconst { callbackFun } = jest.requireActual('./index')Find the method from the original index.js file, otherwise callbackFun will be prompted that it could not be found

The logic of this tutorial is a bit complicated, so be sure to try it out yourself

The next tutorial will cover how to test timers in JEST

My ability is limited, the article may have incorrect or inappropriate parts, I hope you can point out

Pay attention to the public number, and I learn the front-end necessary skills, front-end automation test JEST