0

I am writing unit test cases for a service (built with NestJs) that fetches data with mongoose, nestjs/mongoose packages.

I have simple async method that looks like this (following nestjs's documention found here):

async getMyObjectById(id: string): Promise<MyObject> {
     return await this.model.findById(id).exec();
}

This functioning as expected. I have a basic configuration with mocks for mongoose Queries as seen here:

My test looks like this:

test('find one item by id', async () => {
    jest.spyOn(myMockModel, 'findById').mockResolvedValueOnce('return something');
    const result = await myService.getMyObjectById('1234556');
    expect(result['_id']).toBe('1234556');
});

I get an error related to the .exec() method:

TypeError: this.model.findById(...).exec is not a function

I am able to run this service in dev mode + retrieve information from mongodb, etc. Solutions works just fine. If I remove the .exec() method, mocks works as well. But on the exec() method I am get an undefined. Also tried mocking mongoose Query prototype viz:

jest.spyOn(myMockModel, 'findById').mockResolvedValueOnce(new Query<MyObject, any>());
jest.spyOn(Query.prototype, 'exec').mockResolvedValue('desired value');

and other similar alternatives, but the outcome is the same. Just for the recommendation, I'd like to keep the .exec() method.

Koji D'infinte
  • 1,309
  • 12
  • 20

1 Answers1

0

Based on documentation from jest (Here) use jest.fn().mockReturnThis() is preferred for chaining. I was able to use .mockReturnValue to create an object with the .exec method. Solution looks like this:

test('find one item by id', async () => {
    jest.spyOn(myMockModel, 'findById').mockReturnThis()
    .mockReturnValue({
        exec: jest.fn().mockResolvedValueOnce('return something'),
    } as unknown as Query<MyObject, any>);
    const result = await myService.getMyObjectById('1234556');
    expect(result['_id']).toBe('1234556');
});
Koji D'infinte
  • 1,309
  • 12
  • 20