I have a Person entity with its own Repository class, which I want to test. This repository class injects the Mongoose model as suggested in the docs of NestJS, like so:
@InjectModel(Person.name)
private model: Model<PersonModel>
And the code I'm trying to test is a query similar to const res = await this.model.find().lean();
My issue, though, is when it es to testing the lean() query, as it's a chained function to find() methods. I was able to get as far as I could, but when it es to mocking it I am having some type conflicts:
const modelMockObject = {
find: jest.fn(),
findOne: jest.fn(),
findOneAndUpdate: jest.fn(),
updateOne: jest.fn(),
};
// ...
let MockPersonModel: Model<PersonModel>;
beforeEach(async () => {
const mockModule: TestingModule = await Test.createTestingModule({
providers: [
...,
{
provide: getModelToken(Person.name),
useValue: modelMockObject,
},
],
})pile();
MockPersonModel = mockModule.get<Model<PersonModel>>(
Person.name,
);
});
// ...
// Inside a describe/it test...
const personModel = new MockPersonModel({
name: 'etc'
});
jest.spyOn(MockPersonModel, 'findOne').mockReturnValueOnce({
lean: () => ({ exec: async () => personModel }),
});
The error the linter informs on personModel
(second-last line) is the following:
Type 'Promise<PersonModel>' is not assignable to type 'Promise<P>'.
Type 'PersonModel' is not assignable to type 'P'.
'P' could be instantiated with an arbitrary type which could be unrelated to 'PersonModel'.ts(2322)
index.d.ts(2100, 5): The expected type es from the return type of this signature.
Thanks a lot for your help!
I have a Person entity with its own Repository class, which I want to test. This repository class injects the Mongoose model as suggested in the docs of NestJS, like so:
@InjectModel(Person.name)
private model: Model<PersonModel>
And the code I'm trying to test is a query similar to const res = await this.model.find().lean();
My issue, though, is when it es to testing the lean() query, as it's a chained function to find() methods. I was able to get as far as I could, but when it es to mocking it I am having some type conflicts:
const modelMockObject = {
find: jest.fn(),
findOne: jest.fn(),
findOneAndUpdate: jest.fn(),
updateOne: jest.fn(),
};
// ...
let MockPersonModel: Model<PersonModel>;
beforeEach(async () => {
const mockModule: TestingModule = await Test.createTestingModule({
providers: [
...,
{
provide: getModelToken(Person.name),
useValue: modelMockObject,
},
],
}).pile();
MockPersonModel = mockModule.get<Model<PersonModel>>(
Person.name,
);
});
// ...
// Inside a describe/it test...
const personModel = new MockPersonModel({
name: 'etc'
});
jest.spyOn(MockPersonModel, 'findOne').mockReturnValueOnce({
lean: () => ({ exec: async () => personModel }),
});
The error the linter informs on personModel
(second-last line) is the following:
Type 'Promise<PersonModel>' is not assignable to type 'Promise<P>'.
Type 'PersonModel' is not assignable to type 'P'.
'P' could be instantiated with an arbitrary type which could be unrelated to 'PersonModel'.ts(2322)
index.d.ts(2100, 5): The expected type es from the return type of this signature.
Thanks a lot for your help!
Share Improve this question edited Dec 22, 2020 at 17:33 Manuel Carballido asked Dec 22, 2020 at 17:19 Manuel CarballidoManuel Carballido 451 silver badge8 bronze badges1 Answer
Reset to default 7Maybe too late for you, but for the next one who search to solve this problem like me too.
You can simply use mockImplementation: eg:
MockPersonModel.findOne.mockImplementationOnce(() => ({
lean: jest.fn().mockReturnValue(personModel),
}));
You can check here for more detail about this implementation:
my simple test