更改手动模拟服务中特定功能的模拟实现

Change mockimplementation on specific functions within a manual mocked service

我有服务。

    export const PostService = jest.fn().mockReturnValue({
      findPost: jest.fn().mockResolvedValue(false),
      updatePosts: jest.fn().mockResolvedValue(false),
    });

我将服务导入我的 (nestjs) 测试模块并模拟它。

    import { PostService } from '../post.service';

    jest.mock('../post.service')

    const module: TestingModule = await Test.createTestingModule({
      controllers: [PostController],
      providers: [PostService]
    }).compile();

    postService = module.get<PostService>(PostService);

我想为不同的测试更改模拟 postService 中函数的实现。

    test('findPost should return false', () => {
      postController.getPost() // This calls postService.findPost(), which returns false
    })

    test('findPost should return true', () => {
      // I'm trying to change the implementation here, and then calling the controller
      postService.findPost.mockImplementation(() => true) // Error: mockImplementation is not a function

      postController.getPost() // This should call postService.findPost() and return true
})

如何根据测试用例更改模拟服务中任何功能的实现?例如,如果我想测试一个根据参数抛出错误的服务方法。

测试了两周,阅读了笑话文档,尝试 jest.doMock,摆弄工厂参数,并在每个测试中导入服务并在每个测试用例中模拟它。我能找到的所有更改每个测试用例的 mockImplementation 的示例都是针对单个模拟函数,而不是返回包含多个函数的对象的玩笑函数。

我一般都是这样

const serviceMock = jest.fn(() => ({
    methodMock(): () => { ... }
})

然后,在 beforeEach 函数中将此服务添加为提供者

const module: TestingModule = await Test.createTestingModule({
  controllers: [MyController],
  providers: [
    {
      provide: MyService,
      useValue: serviceMock,
    },
  ],
}).compile();

controller = module.get<MyController>(MyController);

如果我只想对某些测试用例执行此操作,我只需将此代码添加到测试用例中。如果我需要在一堆测试用例中使用它,我将它包装在一个函数中

事实证明解决方案很简单,我只需要:

jest.spyOn("service, "method").mockImplementation(() => { implementation... })

这可以改变任何测试用例中任何模拟函数的实现。