Изменить результаты mockImplementation в SpyOn of jest

SpyOn используется для обнаружения параметров, переданных базовой функции. В некоторых случаях мы хотим изменить результат сквозного вызова и вернуть его вызывающей стороне.

Как нам получить результат вызова в SpyOn до того, как он будет возвращен?

Вот пример:

import {INestApplication} from '@nestjs/common';
import {Test} from '@nestjs/testing';
import {CommonModule} from '@src/common/common.module';
import {Repository} from 'typeorm';
import {User} from '@src/database/entity/user.entity';

describe('AuthService', () => {
    let service: AuthService;
    let app: INestApplication;
    let repo: Repository<User>;

    beforeEach(async () => {
        const module = await Test.createTestingModule({
            imports: [CommonModule],
            providers: [AuthService, {provide: 'USER_REPOSITORY',
                        useValue: mockRepositoryUser()},
           ]}).compile();

        app = module.createNestApplication();
        await app.init();

        service = module.get<AuthService>(AuthService);
        repo = module.get('USER_REPOSITORY');
    });  

    it('test passthrough ', async () => {

        const sp = jest.spyOn(repo , 'findOne').mockImplementation(async (args) => {
           // here we want to first call the original FindOne function 
           // and get the result and then modify that 
           // result and return it. 

           const result  = await originalRepo.findOne(args)  <= ???     
           result.user = {name: 'david'};
           return result;
        );

        service.doWork();
        expect(sp).toHaveBeenCalledTimes(2); 
    });
});

Конечно, в mockImplementation я могу вернуть любое значение. Но скажем, я не хочу статически возвращать значение, а просто хочу использовать базовую базу данных, чтобы получить какой-то результат, а затем изменить его. Поскольку я уже издевался над всем хранилищем с некоторыми действительными данными, каждый раз, когда я вызываю findOne, я получаю действительные результаты. Но чтобы проверить случаи сбоя, я хочу изменить возвращаемые результаты сквозного вызова.

Я надеюсь, что это ясно.


person David Dehghan    schedule 05.06.2020    source источник


Ответы (1)


Ну, похоже, ты не можешь. Главное, что нужно знать, это то, что jest.spyOn — это просто сахар для базового использования jest.fn(). Мы можем достичь той же цели, сохранив исходную реализацию, установив для фиктивной реализации исходную и переназначив оригинал позже:

import * as app from "./app";
import * as math from "./math";

test("calls math.add", () => {
  // store the original implementation
  const originalAdd = math.add;

  // mock add with the original implementation
  math.add = jest.fn(originalAdd);

  // spy the calls to add
  expect(app.doAdd(1, 2)).toEqual(3);
  expect(math.add).toHaveBeenCalledWith(1, 2);

  // override the implementation
  math.add.mockImplementation(() => "mock");
  expect(app.doAdd(1, 2)).toEqual("mock");
  expect(math.add).toHaveBeenCalledWith(1, 2);

  // restore the original implementation
  math.add = originalAdd;
  expect(app.doAdd(1, 2)).toEqual(3);
});

Необходимость в этом будет рассмотрена https://github.com/facebook/jest/issues/6180 Когда мы можем условно возвращать разные значения из макетов.

person David Dehghan    schedule 10.06.2020