Jest测试初学(七)--Jest中的Mock

一 mock函数

在测试中没有提供测试用的数据,那么可以使用jest提供的mock函数,来捕获函数的调用。

const func = jest.fn();  //mock函数,捕获函数的调用

在mock函数里面包含了什么内容?我们可以通过console.log来查看
calls------ 函数被调用返回的结果
instances----- 函数指向的this原型
invocationCallOrder ------ 函数执行的顺序
results----- 函数执行的结果,为数组类型,有返回的类型和返回的值

console.log(func.mock);
    { calls: [ [ 'abc' ], [ 'abc' ] ],       //函数被调用返回的结果
      instances: [ undefined, undefined ],   
      invocationCallOrder: [ 1, 2 ],             //函数执行的顺序
      results:                                             //函数执行的结果,为数组类型,有返回的类型和返回的值
       [ { type: 'return', value: 'Dell' },
         { type: 'return', value: 'Dell' } ] }
    { calls: [ [] ],
      instances: [ mockConstructor {} ],      //函数指向的this原型
      invocationCallOrder: [ 3 ],
      results: [ { type: 'return', value: undefined } ] }

二 用mock写测试用例

证明:

  • 捕获函数的调用和返回结果,以及this和调用顺序
  • 它可以让我们自由地设置返回结果

编写需要测试的函数:

export const runCallback = (callback) => {
   callback('abc');
}

export const createObject = (classItem) => {
    new classItem();
}

编写测试用例:

import { runCallback, createObject } from './demo';

test('测试runCallback',()=>{
    const func = jest.fn();  //mock函数,捕获函数的调用
    //.mockReturnValueOnce 是指调用一次返回的值
    // func.mockReturnValueOnce('Dell');
    // func.mockReturnValueOnce('Lee');
    // func.mockReturnValueOnce('Hello');
    
    //.mockReturnValueOnce/链式调用   
    //func.mockReturnValueOnce('Dell').mockReturnValueOnce('Lee').mockReturnValueOnce('Hello');
   
    //.mockReturnValue 指返回的所有的值
    func.mockReturnValue('Dell');
    
    //调用mock函数
    runCallback(func);
    runCallback(func);
	
	// 测试用例
    // expect(func).toBeCalled();
    // expect(runCallback(func)).toBe('hello');
    // expect(func.mock.calls.length).toBe(2);
    expect(func.mock.calls[0]).toEqual(['abc']);
    expect(func.mock.results[0].value).toBe('Dell');
    console.log(func.mock);
});

test('测试 createObject', ()=>{
    const func = jest.fn();
    createObject(func);
    console.log(func.mock);
});

返回的结果
证明:

  • 它可以改变内部函数的实现
    把异步获取数据的内容变成同步准备数据的内容(让axios同步地模拟数据,而不是真正的发起ajax请求)

编写请求函数

export const getData = () => {
    return axios.get('https://rapi.qingting.fm/recommendations/0/channel_list?more=true&replay=false').then(res =>res.data)
}

编写测试用例

import axios from 'axios';
jest.mock('axios'); //mock模拟整个axios
test.only('测试 getData', async ()=>{
    //单次请求返回
    axios.get.mockResolvedValueOnce({data: 'hello'})
    //多次请求返回
    axios.get.mockResolvedValueOnce({data: 'world'})
    //不希望发真正的ajax请求
    await getData().then((data) => {
        expect(data).toBe('hello');
    })
    await getData().then((data) => {
        expect(data).toBe('world');
    })
});

返回结果

三 小技巧

关于mock返回的内容

     const func = jest.fn(()=>{
        return '456'
     });
     
	//相当于
	func.mockReturnValue('Dell');
	或者是  
	func.mockReturnValueOnce('Dell');

	比两者提供的功能更强的是:
    func.mockImplementationOnce(() => {
        console.log('122');
        return 'Dell'
    });   //单个调用的单次返回
    
    func.mockImplementation(() => {
        console.log('122');
        return 'Dell'
    });   //调用之后返回的全部内容

	//不希望返回任何内容
    func.mockImplementation(() => {
        return this;
    });
    //相当于
    func.mockReturnThis();
    expect(func.mock.results[0].value).toBeUndefined();

	//对于返回的值
	expect(func.mock.calls[0]).toEqual(['abc']);  //第一次返回的是 abc
    expect(func).toBeCalledWith('abc');			//每一次返回的都应该是abc

四 小总结----mock函数的作用

  • 捕获函数的调用和返回结果,以及this和调用顺序
  • 它可以让我们自由地设置返回结果
  • 它可以改变内部函数的实现

猜你喜欢

转载自blog.csdn.net/xiaoyangzhu/article/details/101149595