Как смоделировать функцию в Jest - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть следующий класс машинописи, который я хочу проверить в 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' );
  } );
} );

Как мне сменить функцию foo, используемую в MyClass, чтобы этот тест прошел?

1 Ответ

0 голосов
/ 12 ноября 2018

Есть несколько способов подойти к нему.


Вы можете издеваться только foo, используя jest.spyOn и что-то вроде mockImplementation:

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
  });
});

Аналогично, вы можете автоматически смоделировать FooFactory с помощью jest.mock, а затем предоставить реализацию для 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
  });
});

Вы также можете высмеивать FooFactory, используя фабрику модулей, переданную в jest.mock:

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:

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
  });
});
...