Home > Enterprise >  Change mockimplementation on specific functions within a manual mocked service
Change mockimplementation on specific functions within a manual mocked service

Time:04-05

I have a service.

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

I import the service into my (nestjs) test module and mock it.

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

I want to change the implementation of functions inside the mocked postService for different tests.

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

How can I change the implementation of any of the functions inside the mocked service depending on the test cases? For example, if I want to test a service method that throws an error depending on the parameters.

Been testing for two weeks, reading the jest docs, trying jest.doMock, messing around with the factory parameter, and importing the service per test and mocking it per test case. All the examples I could find of changing the mockImplementation per test case is for a single mocked function, not a jest function returning an object that contains multiple functions.

CodePudding user response:

I am usually do it like this

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

Then, in beforeEach function add this service as a provider

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

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

And if i want to do this only for some of the test cases, i just add this code to testcase. If i need to use it in a bunch of test cases, i wrap it in a function

CodePudding user response:

It turns out the solution is simple, all I needed was:

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

This can change the implementation of any mock function in any test cases.

  • Related