Basic introduction
Hook function
- Scope and the order in which hooks are executed under different scopes
- Describe and test blocks execution order. Finish the describe layer code and then execute test
- You can use test.only(“,()=>{}) to execute only one test case
Global setting
Jest contains globally-defined objects and functions that can be used directly.
- test()
- describe()
- beforeEach()
matcher
- toBe() toEqual() toStrictEqual()
test.only('object equal'.() = >{
let obj1 = {
name:'jack'.age:12.friends: ['rose']}let obj2 = {
name:'jack'.age:12.friends: ['rose'].address:undefined
}
let obj3 = obj1
expect(obj1).toEqual(obj2) // key-value compares key-value pairs
expect(obj1).toStrictEqual(obj2) // Compare keys and values hasOwnProperty()
expect(obj1).toBe(obj3) Object. Is (obj1,obj2)
})
Copy the code
Timer simulation
jest.useFakeTimers(‘legacy’)
- use
toHaveBeenLastCalledWith
Determines the incoming argument to the last call to setTimeout()
test('call'.() = >{
let fn = jest.fn(() = >{})
fn('foo')
//fn('foo1')
expect(fn).toHaveBeenLastCalledWith('foo') // The last call to fn takes an argument of foo
})
Copy the code
jest.useFakeTimers(); // fake timers
// The last call to timer is passed as an argument
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 1000);
Copy the code
- expect.any(constructor)
As an instance of the constructor, can match any instance of the constructor.
test('call'.() = >{
let a = 1
expect(a).toEqual(expect.any(Number)) // true
})
test('call'.() = >{
let fn = jest.fn(() = >{})
fn(1)
expect(fn).toBeCalledWith(expect.any(Number))})Copy the code
- How can I tell if a function is executed instead of being used
expect.any(Function)
const handle = timerGame(fn);
expect(setTimeout).toHaveBeenLastCalledWith(handle, 1000);
Copy the code
jest.advanceTimersByTime(1000)
Fast forward
// The difference between the two is to pass a setTimeout parameter
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 1000);
// This is to determine whether the callback we passed is executed
expect(callback).toBeCalled();
Copy the code
jest.useFakeTimers(‘modern’)
Jest. UseFakeTimers (‘ modern ‘) and jest setSystemTime (number | Date), is used to simulate the Date
mock
A mock function
Why mock functions?
- Capture function calls
toHaveBeenCalled
Mock functions must be used - Sets the return value of the function
- Change the internal implementation of a function
describe('mock function'.() = >{
test.only('mock.fn'.() = >{
let mockFn = jest.fn((arg) = >arg + ' is passed')
let result = curry(mockFn)('foo')
expect(mockFn).toBeCalled()
expect(mockFn).toHaveBeenCalled();
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenCalledWith("foo");
expect(result).toBe('foo is passed')})})Copy the code
The mock module
See WXB – manager/utils. Test. Js test commonUploadPictureOrFile method, rely on a lot of other configuration, and we care about it depends on the configuration, only consider the input leads to different output function.
Create a __mocks__ folder to place the manually emulated modules. The search priority is higher than node_modules
// __mocks__/axios
const get = url= > {
return Promise.resolve({ data: { title: 'delectus aut autem'}}); };const post = url= >{
if(url === 'https://wxb-manger/userinfo') {return Promise.resolve({
data: {userInfo: {isAdmin:true.expired:false}})}}exports.get = get;
exports.post = post
Copy the code
// __mocks__/lodash
module.exports = {
chunk(arr,len) {
let length = arr.length
let i = 0
let store = []
while(i<length){
store.push(arr.slice(i,i+len))
i+=len
}
return store
}
}
Copy the code
Asynchronous code testing
test("callback was't called".() = >{
const callback = data= >{
expect(data).toBe('suc') // The assertion will not be executed
}
asyncHandle(callback)
})
Copy the code
- Use the done() callback provided by test
test('callback called'.(done) = >{
const callback = data= >{
expect(data).toBe('suc')
done()
}
asyncHandle(callback)
})
Copy the code
- Perform assertions on promise.then()
test('called in promise.then'.() = >{
asyncHandle().then(res= >{
expect(res).toBe('suc')})})Copy the code
- Use async functions
test('async'.async() = > {let res = await asyncHandle()
expect(res).toBe('suc')})Copy the code
engineering
Babel configuration
If you need to be compatible with the previous Babel configuration in an existing project, Jest will set process.env.node_env to ‘test’ to determine whether the environment is compatible with the Babel configuration required by jest and the Babel configuration of the project.
// babel.config.js
module.exports = api= > {
const isTest = api.env('test');
const jestConfig = { / *... * /}
const projectConfig = { / *... * /}
return isTest ? jestConfig : projectConfig
};
Copy the code
Jest configuration file
jest --init
- Config jest
module.exports = {
moduleFileExtensions: [
"js"."ts"."json"."vue"].// Use the new function
transform: {
"\\.ts$": ['ts-jest']."\\.js$": ['babel-jest', {rootMode: "upward"}].// Use 'vue-jest' to process '*. Vue' files
".*\\.(vue)$": "vue-jest"."^.+\\.tsx? $": "ts-jest"
},
transformIgnorePatterns: [ // Ignore file translation in this path
"/node_modules/"."\\.pnp\\.[^\\/]+$"].testPathIgnorePatterns: [ // Ignore the test files in this path
"/node_modules/"].clearMocks: true.// Each test clears the mock directly
moduleNameMapper: {/ / map mapping
"^ @ / (. *) $":"<rootDir>/src/$1"."^assets/(.*)$": [
"<rootDir>/images/$1"."<rootDir>/photos/$1"."<rootDir>/recipes/$1"]}}Copy the code
jest CLI
jest --watch
Listening for file changesjest -o async.test.js example.test.js
Run only the specified template
Debug
Configuration of Launch and Attach modes
Vscode debug configuration
Better Tests
- TDD(Test Driven Development) defines the points we need to Test from the Test cases listed in QA before Development (the process of combing the requirements document).
- Pay attention to the design of test granularity.
- For modules that change frequently, we can write tests based on function points, so that the function does not change without internal implementation.
- Functions and classes can test detailed function points.
- Ensure the reliability of the test
- Independent of external conditions, ensure that one input corresponds to one output.
- Include fail and success.
- Tests are not interdependent states.
- Avoid mock methods, class private methods, and attributes.
- Test maintainability
-
Extract the duplicate code into the preceding constructor
-
Use more matchers to improve readability
-
Keep the logic of your tests simple and granular. Avoid code changes that modify too many test cases
-
The complete code
The source code