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.js
andindex.test.js
Delete 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
- here
jest.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.mock
Each 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,
mockImplementationOnce
和mockReturnValueOnce
Set the return value of the function once, but with more power, you can write more logic inside the function mockImplementation
和mockReturnValue
The 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
- will
index.test.js
Content to delete - Root Directory Creation
__mocks__
Folder, create a new folder insideindex.js
And write the following content
// Return a promise
export function getData() {
return new Promise(resolve= > {
resolve({
data: 'Test data'})})}Copy the code
- in
index.test.js
Write 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 it
const { 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