Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot test e2e because Nestjs doesn't resolve dependencies

I have the following error :

Nest can't resolve dependencies of the ParametrageRepository (?). Please make sure that the argument DataSource at index [0] is available in the TypeOrmModule context.

My test code :

describe("ParametrageController (e2e)", () => {
    let parametrage: INestApplication;

    beforeEach(async () => {
        const moduleFixture: TestingModule = await Test.createTestingModule({
            imports: [ParametrageModule],
        }).compile();

        parametrage = moduleFixture.createNestApplication();
        await parametrage.init();
    });

    it("/ (POST)", () =>
        request(parametrage.getHttpServer())
            .post("/parametrage")
            .send({
                libelle: "GROUPE_TYPE",
                liste: ["TEAM", "SERVICE", "ORGANISATION"],
            })
            .expect(201));
});

My module code:

@Module({
    imports: [TypeOrmModule.forFeature([Parametrage])],
    exports: [TypeOrmModule],
    controllers: [ParametrageController],
    providers: [ParametrageService, ParametrageRepository, ParametrageActions, Logger],
})
export class ParametrageModule {}

I cannot tel why I have this error since I followed the Nestjs documentation. Maybe I skipped a part I don't know. Maybe it's because of my providers that has parameters in their constructors :

My ParametrageRepository provider :

@Injectable()
export class ParametrageRepository
    extends RepositoryStarter<Parametrage, IParametrageListFilter>
    implements IParametrageRepository
{
    constructor(@InjectDataSource() datasource: DataSource) {
        super(datasource.getRepository(Parametrage));
    }

I tried to add providers injection :

const moduleFixture: TestingModule = await Test.createTestingModule({
    imports: [ParametrageModule],
**      providers: [
                 { provide: ParametrageActions, useValue: ParametrageActions },
                 { provide: ParametrageRepository, useValue: ParametrageRepository },
                         { provide: Logger, useValue: Logger ,
                ],**
}).compile();

But stil the same error, it didn't solved anything

Thanks in advance

like image 257
Sam Avatar asked Oct 17 '25 00:10

Sam


1 Answers

The error says that it cannot resolve the DataSource. That means that the module has extraneous dependencies which you need provide or mock.

There several ways:

  1. Use the a testing database, then you will need to
const moduleFixture: TestingModule = await Test.createTestingModule({
  imports: [TypeOrm.forRoot(databaseConfig), ParametrageModule],
}).compile();

This will inject the DataSource and you will be able to work with the Repositories.

  1. You can provide a mock implementation of the DataSource:
const moduleFixture: TestingModule = await Test.createTestingModule({
  imports: [ParametrageModule],
  provide: [{ provide: DataSource, useFactory: dataSourceMockFactory }]

}).compile();

Where dataSourceMockFactory is a function that returns the object that has the methods you are using.

  1. Instead of importing the whole module you can declare it in place and provide a mock of the repository:
const moduleFixture: TestingModule = await Test.createTestingModule({
  controllers: [ParametrageController],
  providers: [ParametrageService, { provide: ParametrageRepository, useFactory: parametrageRepositoryMockFactory, ParametrageActions, Logger],

You will have to provide parametrageRepositoryMockFactory. But you don't have to mock all the methods a real Repository would provide, just those you are going to need during the test. I.E.:

const parametrageRepositoryMockfactory = () => ({
  findAll: () => Promise.resolve([]),
  create: (data) => Promise.resolve(data),
})

I would suggest to start with the first approach (testing DB), since it's the easiest one and also gives the real results, not just mocks. Thus it's more reliable. note that you shouldn't use the same DB as for the production, since tests will use it and might create/update/delete data.

The second and third approaches can be used for unit tests, but I don't think it's the right choice in this case.

like image 149
Dmitrii Tkachenko Avatar answered Oct 19 '25 13:10

Dmitrii Tkachenko