I am trying to set up my test suite for a specific service which takes in a repository and two other services at the constructor parameter level injection using Nest's built-in Dependency Injection (DI). The application is working fine no issue there. But when testing it returns:
Nest can't resolve dependencies of the AdjustmentService (?, RetailAdjustmentService, AdjustmentFileService). Please make sure that the argument AdjustmentRepository at index [0] is available in the RootTestModule context.
i know there must be something i am doing wrong but the docs were not of much help regarding that.
here is the constructor of that specific service i am testing :
export class AdjustmentService {
constructor(
private readonly adjustmentsRepository: AdjustmentRepository,
private readonly _retailAdjustmentService: RetailAdjustmentService,
private readonly adjustmentFilesService: AdjustmentFileService
) {}
//service functions here...
}
and here is my test
import { AdjustmentFileService } from "@/services/adjustmentFile.service";
import { Test, TestingModule } from "@nestjs/testing";
import { AdjustmentService } from "./adjustment.service";
import { Repository } from "typeorm";
import { AdjustmentEntity } from "@/entities/adjustment.entity";
import { getRepositoryToken } from "@nestjs/typeorm";
import { RetailAdjustmentService } from "@/services/retail/retailAdjustment.service";
describe("Adjustment Service", () => {
let adjustmentService: AdjustmentService;
let adjustementRepository: Repository<AdjustmentEntity>;
beforeEach(async () => {
const module = await Test.createTestingModule({
providers: [
AdjustmentService,
AdjustmentFileService,
RetailAdjustmentService,
{
provide: getRepositoryToken(AdjustmentEntity),
useValue: {
save: jest.fn(),
createQueryBuilder: jest.fn(),
delete: jest.fn(),
where: jest.fn(),
execute: jest.fn(),
},
},
],
}).compile();
adjustmentService = module.get<AdjustmentService>(AdjustmentService);
adjustementRepository = module.get<Repository<AdjustmentEntity>>(
getRepositoryToken(AdjustmentEntity)
);
});
describe("updateAdjustment", () => {
it("should update the adjustment", async () => {
const repoSpy = jest
.spyOn(adjustementRepository, "save")
.mockResolvedValue({ id: 1 } as AdjustmentEntity);
const adjToUpdate = new AdjustmentEntity();
adjToUpdate.id = 1;
adjToUpdate.pilars = "RT";
adjToUpdate.amount = 15000;
expect(
adjustmentService.updateAdjustment(1, adjToUpdate)
).resolves.toEqual({ id: 1 });
expect(repoSpy).toBeCalledWith(adjToUpdate);
});
});
it("should return a list of adjustments", async () => {});
});
If you are wanting to create mocks of these services, which you should in unit tests, then you should make custom providers that have a provide
property of the class you want to mock and a useValue
property of the mock to use. For example, AdjustmentFileService
's mock might look something like
{
provide: AdjustmentFileService,
useValue: {
upload: jest.fn()
}
}
You're on the right track with the getRepositoryToken
approach, but as your AdjustmentRepository
is a class you directly inject, you need to use AdjustmentRepository
as the provide
value as well.
This repository has a lot of testing examples and might serve as a good reference.