在开玩笑的SpyOn中修改嘲笑实现

时间:2020-06-05 23:26:54

标签: angular unit-testing jestjs typeorm spyon

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

当然,在模拟实现中,我可以返回任何值。但是,让我们说我不想静态地返回一个值,而只想使用基础数据库来获取一些结果,然后对其进行修改。由于我每次调用findOne时都已经用一些有效数据模拟了整个商店,所以我得到了有效的结果。但是,为了测试失败的情况,我想修改通过调用返回的结果。

我希望这很清楚。

1 个答案:

答案 0 :(得分:0)

好吧,看来你做不到。要知道的关键是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将满足我们的需求,前提是我们可以有条件地从模拟返回不同的值。