Jest 模拟函数API

2021-09-23 20:25 更新

模拟函数也被称为“间谍”,因为它们让你可以监视由其他代码间接调用的函数的行为,而不仅仅是测试输出。你可以使用​jest.fn()​. 如果没有给出实现,模拟函数将​undefined​在调用时返回。

方法

参考

mockFn.getMockName()

返回通过调用设置的模拟名称字符串​mockFn.mockName(value)​。

mockFn.mock.calls

包含对此模拟函数进行的所有调用的调用参数的数组。数组中的每一项都是调用期间传递的参数数组。

例如:一个模拟函数f被调用了两次,使用参数​f('arg1', 'arg2')​,然后使用参数​f('arg3', 'arg4')​,将有一个如下所示的​mock.calls​数组:

  1. [
  2. ['arg1', 'arg2'],
  3. ['arg3', 'arg4'],
  4. ];

mockFn.mock.results

一个数组,包含对此模拟函数进行的所有调用的结果。此数组中的每个条目都是一个包含​type​属性和​value​属性的对象。​type​将是以下之一:

  • 'return'​ - 表示呼叫通过正常返回完成。
  • 'throw'​ - 表示通过抛出一个值来完成调用。
  • 'incomplete'​- 表示呼叫尚未完成。如果你从模拟函数本身或从模拟调用的函数中测试结果,则会发生这种情况。

value​属性包含抛出或返回的值。​当​type === 'incomplete'时,value​未定义​。

例如:一个模拟函数​f​被调用了 3 次,返回​'result1'​,抛出错误,然后返回​'result2'​,将有一个如下所示的​mock.results​数组:

  1. [
  2. {
  3. type: 'return',
  4. value: 'result1',
  5. },
  6. {
  7. type: 'throw',
  8. value: {
  9. /* Error instance */
  10. },
  11. },
  12. {
  13. type: 'return',
  14. value: 'result2',
  15. },
  16. ];

mockFn.mock.instances

一个数组,其中包含已使用此模拟函数实例化的所有对象实例​new​。

例如:已实例化两次的模拟函数将具有以下​mock.instances​数组:

  1. const mockFn = jest.fn();
  2. const a = new mockFn();
  3. const b = new mockFn();
  4. mockFn.mock.instances[0] === a; // true
  5. mockFn.mock.instances[1] === b; // true

mockFn.mockClear()

重置存储在mockFn.mock.callsmockFn.mock.instances数组中的所有信息。

当你想要清理两个断言之间的模拟使用数据时,这通常很有用。

当心,mockClear将取代mockFn.mock,而不仅仅是mockFn.mock.callsmockFn.mock.instances。因此,你应该避免分配​mockFn.mock​给其他变量,无论是临时的还是非临时的,以确保你不会访问过时的数据。

clearMocks配置选项可用于在测试之间自动清除模拟。

mockFn.mockReset()

执行所有mockFn.mockClear()操作,并删除任何模拟的返回值或实现。

当你想要完全重置 mock 到初始状态时,这是有用。 (注意重置一个 spy 将导致一个没有返回值的函数)。

当心,​mockReset​将取代​mockFn.mock​,而不仅仅是mockFn.mock.callsmockFn.mock.instances。因此,你该避免分配​mockFn.mock​给其他变量,无论是临时的还是非临时的,以确保你不会访问过时的数据。

mockFn.mockRestore()

执行所有mockFn.mockReset()操作,并恢复原始(非模拟)实现。

当你想在某些测试用例中模拟函数并在其他测试用例中恢复原始实现时,这很有用。

请注意,​mockFn.mockRestore​只有在使用​jest.spyOn​. 因此,你必须在手动分配​jest.fn()​.

restoreMocks配置选项可用于在测试之间自动恢复模拟。

mockFn.mockImplementation(fn)

接受一个应该用作模拟实现的函数。模拟本身仍然会记录进入的所有调用和来自自身的实例——唯一的区别是当模拟被调用时,实现也会被执行。

注意:​jest.fn(implementation)​是 的简写​jest.fn().mockImplementation(implementation)​。

例如:

  1. const mockFn = jest.fn().mockImplementation(scalar => 42 + scalar);
  2. // or: jest.fn(scalar => 42 + scalar);
  3. const a = mockFn(0);
  4. const b = mockFn(1);
  5. a === 42; // true
  6. b === 43; // true
  7. mockFn.mock.calls[0][0] === 0; // true
  8. mockFn.mock.calls[1][0] === 1; // true

mockImplementation ​也可用于模拟类构造函数:

  1. // SomeClass.js
  2. module.exports = class SomeClass {
  3. m(a, b) {}
  4. };
  5. // OtherModule.test.js
  6. jest.mock('./SomeClass'); // this happens automatically with automocking
  7. const SomeClass = require('./SomeClass');
  8. const mMock = jest.fn();
  9. SomeClass.mockImplementation(() => {
  10. return {
  11. m: mMock,
  12. };
  13. });
  14. const some = new SomeClass();
  15. some.m('a', 'b');
  16. console.log('Calls to m: ', mMock.mock.calls);

mockFn.mockImplementationOnce(fn)

接受一个函数,该函数将用作对模拟函数的一次调用的模拟实现。可以链接,以便多个函数调用产生不同的结果。

  1. const myMockFn = jest
  2. .fn()
  3. .mockImplementationOnce(cb => cb(null, true))
  4. .mockImplementationOnce(cb => cb(null, false));
  5. myMockFn((err, val) => console.log(val)); // true
  6. myMockFn((err, val) => console.log(val)); // false

当模拟函数用完用 ​mockImplementationOnce ​定义的实现时,它将执行设置的默认实现,​jest.fn(() => defaultValue)​或者​.mockImplementation(() => defaultValue)​如果它们被调用:

  1. const myMockFn = jest
  2. .fn(() => 'default')
  3. .mockImplementationOnce(() => 'first call')
  4. .mockImplementationOnce(() => 'second call');
  5. // 'first call', 'second call', 'default', 'default'
  6. console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());

mockFn.mockName(value)

接受在测试结果输出中使用的字符串代替​“jest.fn()”​以指示正在引用哪个模拟函数。

例如:

  1. const mockFn = jest.fn().mockName('mockedFunction');
  2. // mockFn();
  3. expect(mockFn).toHaveBeenCalled();

会导致这个错误:

  1. expect(mockedFunction).toHaveBeenCalled()
  2. Expected mock function "mockedFunction" to have been called, but it was not called.

mockFn.mockReturnThis()

语法糖函数用于:

  1. jest.fn(function () {
  2. return this;
  3. });

mockFn.mockReturnValue(value)

接受一个将在调用模拟函数时返回的值。

  1. const mock = jest.fn();
  2. mock.mockReturnValue(42);
  3. mock(); // 42
  4. mock.mockReturnValue(43);
  5. mock(); // 43

mockFn.mockReturnValueOnce(value)

接受将在一次调用模拟函数时返回的值。可以链接,以便对模拟函数的连续调用返回不同的值。当没有更多​mockReturnValueOnce​值可以使用时,调用将返回一个由 指定的值​mockReturnValue​。

  1. const myMockFn = jest
  2. .fn()
  3. .mockReturnValue('default')
  4. .mockReturnValueOnce('first call')
  5. .mockReturnValueOnce('second call');
  6. // 'first call', 'second call', 'default', 'default'
  7. console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());

mockFn.mockResolvedValue(value)

语法糖函数用于:

  1. jest.fn().mockImplementation(() => Promise.resolve(value));

在异步测试中模拟异步函数很有用:

  1. test('async test', async () => {
  2. const asyncMock = jest.fn().mockResolvedValue(43);
  3. await asyncMock(); // 43
  4. });

mockFn.mockResolvedValueOnce(value)

语法糖函数用于:

  1. jest.fn().mockImplementationOnce(() => Promise.resolve(value));

用于解决多个异步调用的不同值:

  1. test('async test', async () => {
  2. const asyncMock = jest
  3. .fn()
  4. .mockResolvedValue('default')
  5. .mockResolvedValueOnce('first call')
  6. .mockResolvedValueOnce('second call');
  7. await asyncMock(); // first call
  8. await asyncMock(); // second call
  9. await asyncMock(); // default
  10. await asyncMock(); // default
  11. });

mockFn.mockRejectedValue(value)

语法糖函数用于:

  1. jest.fn().mockImplementation(() => Promise.reject(value));

用于创建始终拒绝的异步模拟函数:

  1. test('async test', async () => {
  2. const asyncMock = jest.fn().mockRejectedValue(new Error('Async error'));
  3. await asyncMock(); // throws "Async error"
  4. });

mockFn.mockRejectedValueOnce(value)

语法糖函数用于:

  1. jest.fn().mockImplementationOnce(() => Promise.reject(value));

用法示例:

  1. test('async test', async () => {
  2. const asyncMock = jest
  3. .fn()
  4. .mockResolvedValueOnce('first call')
  5. .mockRejectedValueOnce(new Error('Async error'));
  6. await asyncMock(); // first call
  7. await asyncMock(); // throws "Async error"
  8. });


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号