Jest Mock的使用

在使用jest 单元测试中,mock 是非常重要的!
1、捕获函数的调用和返回的结果,以及this和调用顺序

2、它可以让我们自由的设置返回结果

3、改变函数的内部实现

下面介绍mock 的一些方法使用:

首先需要了解:jest.fn()

jest对象

  • jest.fn(implementation):返回一个全新没有使用过的mock function,这个function在被调用的时候会记录很多和函数调用有关的信息,是创建Mock函数最简单的方式,如果没有定义函数内部的实现,jest.fn()会返回undefined作为返回值。

  • jest.mock(moduleName, factory, options):用来mock一些模块或者文件

  • jest.spyOn(object, methodName):返回一个mock function,和jest.fn相似,但是能够追踪object[methodName]的调用信息,类似Sinon

test('测试jest.fn()调用', () => {
  let mockFn = jest.fn();
  let result = mockFn(1, 2, 3);

  // 断言mockFn的执行后返回undefined
  expect(result).toBeUndefined();
  // 断言mockFn被调用
  expect(mockFn).toBeCalled();
  // 断言mockFn被调用了一次
  expect(mockFn).toBeCalledTimes(1);
  // 断言mockFn传入的参数为1, 2, 3
  expect(mockFn).toHaveBeenCalledWith(1, 2, 3);
})

jest.fn()所创建的Mock函数还可以设置返回值,定义内部实现或返回Promise对象。

test('测试jest.fn()返回固定值', () => {
  let mockFn = jest.fn().mockReturnValue('default');
  // 断言mockFn执行后返回值为default
  expect(mockFn()).toBe('default');
})

test('测试jest.fn()内部实现', () => {
  let mockFn = jest.fn((num1, num2) => {
    return num1 * num2;
  })
  // 断言mockFn执行后返回100
  expect(mockFn(10, 10)).toBe(100);
})

test('测试jest.fn()返回Promise', async () => {
  let mockFn = jest.fn().mockResolvedValue('default');
  let result = await mockFn();
  // 断言mockFn通过await关键字执行后返回值为default
  expect(result).toBe('default');
  // 断言mockFn调用后返回的是Promise对象
  expect(Object.prototype.toString.call(mockFn())).toBe("[object Promise]");
})

mockReturnValue()

模拟返回结果。指定返回内容
函数内的参数就是要 返回的值

const func = jest.fn()
func.mockReturnValue('dell')
// func函数调用,return 'dell'

例如某些情况需要让函数方法返回指定的内容:

import React from 'react';
import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
import NavigationBar from './index';

jest.mock('@tarojs/taro', () => ({
  getStorageSync: jest.fn().mockReturnValue({
    bindPhone: '10086'
  })
}));

mockReturnValueOnce()

模拟返回结果。执行一次,指定返回内容
mockReturnValue执行返回多次,mockReturnValueOnce只会执行返回一次

jest.mock('@tarojs/taro', () => ({
  getStorageSync: jest.fn().mockReturnValueOnce({
    bindPhone: '10086'
  })
}));

mockImplementation()

模拟返回结果,可以理解为mockReturnValue()的底层写法
可以在方法内书写过程

// demo.js
export const runCallBack = (callBack) => {
  callBack()
}

// demo.test.js
import { runCallBack } from './demo.js'

test('测试 runCallBack的回调', () => {
  const func = jest.fn()
  func.mockImplementation(() => {
 		return 'dell'
	})
  runCallBack(func)
  expect(func.mock.results[0].value).toBe('dell')
})


====== // 等同于
const func = jest.fn(() => {
  return 'dell'
})

mockImplementationOnce()

模拟返回结果,执行一次

const func = jest.fn()

func.mockImplementationOnce(() => {
 return 'dell'
})
func.mockImplementationOnce(() => {
 return 'yang'
})

expect(func.mock.calls.length).toBe(2)
expect(func.mock.results[0].value).toBe('dell')
expect(func.mock.results[1].value).toBe('yang')

mockResolvedValue()

Promise resolve 返回的值


mockResolvedValueOnce()

// mock resolve value 运行 once
axios.get.mockResolvedValueOnce({data:'hello world'})

mockReturnThis()

模拟返回this


requireActual

让其以真实的方式运行

jest.requireActual('lodash-es');

useFakeTimers()

export default (callback) => {
	setTimeout(() => {
		callback()
	},3000)
}


import timer from './timer'

// 运行time测试时,不使用真实setTimeout
jest.useFakeTimers()

test('定时器测试',() => {
	const fn = jest.fn()
	timer(fn)
	jest.runAllTimers() // 所有timer立即执行,不等待
	expect(fn).toHaveBeenCalledTimes(1)
})

runAllTimers()

// 与useFakeTimers 匹配使用
import timer from './timer'

// 运行time测试时,不使用真实setTimeout
jest.useFakeTimers()

test('定时器测试',() => {
	const fn = jest.fn()
	timer(fn)
	jest.runAllTimers() // 所有timer立即执行,不等待
	expect(fn).toHaveBeenCalledTimes(1)
})

runOnlyPendingTimers()

// 只处理当前队列中即将执行的Timer,不会运行没有创建的Timer

export default (callback) => {

	setTimeout(() => {
		callback()
		setTimeout(() => {
			callback()
		},3000)
	},3000)
}


import timer from './timer'

// 运行time测试时,不使用真实setTimeout
jest.useFakeTimers()

test('定时器测试',() => {
	const fn = jest.fn()
	timer(fn)
	jest.runOnlyPendingTimers() 
	expect(fn).toHaveBeenCalledTimes(1)
})

advanceTimersByTime(waitTime)

// 让timer 快进 waitTime 时间
// jest.advanceTimersByTime()
 
 export default (callback) => {
	setTimeout(() => {
		callback()
	},3000)
}

import timer from './timer'

// 运行time测试时,不使用真实setTimeout
jest.useFakeTimers()

test('定时器测试',() => {
	const fn = jest.fn()
	timer(fn)
	jest.advanceTimersByTime(3000) // timer立即快进3000ms
	expect(fn).toHaveBeenCalledTimes(1)
})

官网还有很多匹配器

Jest官网

Api Reference ==》 Expect ===》 Methods 中查找

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值