【问题标题】:Modify mockImplementation results in SpyOn of jest修改 mockImplementation 导致 SpyOn 的玩笑
【发布时间】:2020-06-05 23:26:54
【问题描述】:

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 时都已经用一些有效数据模拟了整个商店,所以我得到了有效的结果。但是为了测试失败案例,我想修改调用返回的结果。

我希望这很清楚。

【问题讨论】:

    标签: angular unit-testing jestjs typeorm spyon


    【解决方案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 将解决这个需求,当我们可以有条件地从模拟返回不同的值时。

    【讨论】:

      猜你喜欢
      • 2020-11-14
      • 2019-10-28
      • 1970-01-01
      • 2021-12-16
      • 1970-01-01
      • 2021-11-14
      • 2020-12-31
      • 2018-11-14
      • 2020-08-11
      相关资源
      最近更新 更多