如何在 Jest 中模拟一个函数

Posted

技术标签:

【中文标题】如何在 Jest 中模拟一个函数【英文标题】:How to mock a function in Jest 【发布时间】:2019-04-09 23:33:58 【问题描述】:

我有以下要在 Jest 中测试的打字稿类。

//MyClass.ts
import  foo  from './somewhere/FooFactory';
export class MyClass 
  private _state : number;
  constructor( arg : string ) 
    this._state = foo( arg );
  

  public getState() : string 
    return this._state;
  

这是我的测试:

//MyClass.spec.ts
import  MyClass  from './MyClass';
describe( 'test MyClass', () => 
  test( 'construct' => 
    const c = new MyClass( 'test' );
    expect( c ).toBeDefined();
    expect( c.getState() ).toEqual( 'TEST' );
   );
 );

如何模拟 MyClass 中使用的 foo 函数以使该测试通过?

【问题讨论】:

看起来和***.com/questions/40465047/…一样 【参考方案1】:

有几种不同的方法来处理它。


您只能使用jest.spyOnmockImplementation 之类的东西模拟foo

import  MyClass  from './MyClass';
import * as FooFactory from './somewhere/FooFactory';

describe('test MyClass', () => 
  test('construct', () => 
    const mock = jest.spyOn(FooFactory, 'foo');  // spy on foo
    mock.mockImplementation((arg: string) => 'TEST');  // replace implementation

    const c = new MyClass('test');
    expect(c).toBeDefined();
    expect(c.getState()).toEqual('TEST');  // SUCCESS

    mock.mockRestore();  // restore original implementation
  );
);

同样,您可以使用jest.mock 自动模拟FooFactory,然后为foo 提供一个实现:

import  MyClass  from './MyClass';
import * as FooFactory from './somewhere/FooFactory';

jest.mock('./somewhere/FooFactory');  // auto-mock FooFactory

describe('test MyClass', () => 
  test('construct', () => 
    const mockFooFactory = FooFactory as jest.Mocked<typeof FooFactory>;  // get correct type for mocked FooFactory
    mockFooFactory.foo.mockImplementation(() => 'TEST');  // provide implementation for foo

    const c = new MyClass('test');
    expect(c).toBeDefined();
    expect(c.getState()).toEqual('TEST');  // SUCCESS
  );
);

您还可以使用传递给jest.mock 的模块工厂模拟FooFactory

import  MyClass  from './MyClass';

jest.mock('./somewhere/FooFactory', () => (
  foo: () => 'TEST'
));

describe('test MyClass', () => 
  test('construct', () => 
    const c = new MyClass('test');
    expect(c).toBeDefined();
    expect(c.getState()).toEqual('TEST');  // SUCCESS
  );
);

最后,如果您打算在多个测试文件中使用相同的模拟,您可以通过在./somewhere/__mocks__/FooFactory.ts 创建模拟来mock the user module:

export function foo(arg: string) 
  return 'TEST';

...然后调用jest.mock('./somewhere/FooFactory'); 在测试中使用模拟:

import  MyClass  from './MyClass';

jest.mock('./somewhere/FooFactory');  // use the mock

describe('test MyClass', () => 
  test('construct', () => 
    const c = new MyClass('test');
    expect(c).toBeDefined();
    expect(c.getState()).toEqual('TEST');  // SUCCESS
  );
);

【讨论】:

我登录 *** 只是为了支持这个答案。非常感谢。 这很有帮助!

以上是关于如何在 Jest 中模拟一个函数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Jest 模拟对象中的特定函数?

如何在每次测试之前重置 Jest 模拟函数调用计数

如何使用 Jest 模拟 JavaScript 窗口对象?

如何清除 Jest 模拟实现以进行下一次测试?

如何使用 Jest 模拟异步函数

Jest - 模拟函数,从另一个文件导入