Nest JS two instances of the same provider

后端 未结 1 1546
故里飘歌
故里飘歌 2020-12-06 09:02

Hi on a test suite it appears to me that I have 2 living instances of a same provider, one for the implementation and another one for the real implementation.

I base

相关标签:
1条回答
  • 2020-12-06 09:17

    You are mixing the concepts of unit tests and end to end (e2e) tests. You are importing a module and at the same time you import single providers directly. I'm assuming that one of your imported modules also imports ExamCacheResultService. This way, you have two of them in your test application. When you call app.get(ExamCacheResultService), you will get the instance that is directly declared in your testing module. But the one that is used when you call finishApplication is the other one. Decide what you want to test and follow the following principles:

    Unit test

    In a unit test you want to test a single provider/controller isolated from other dependencies, e.g. UserService or UsersController. You import this provider and its injected dependencies as mocks. You do not import a module.

    Let's assume we have a UsersService that depends on a DatabaseConnection:

    export class UsersService {
      constructor(private connection: DatabaseConnection) {}
      // ...
    }
    

    In your unit test, you import the UsersService, you mock the DatabaseConnection but you do not import the UsersModule.

    module = await Test.createTestingModule({
      providers: [
        UsersService,
        { provide: DatabaseConnection, useClass: DbConnectionMock },
      ],
    }).compile();
    databaseMock = module.get(DatabaseConnection);
    databaseMock.findMany.mockReturnValue([]);
    

    E2E test

    In an end to end test, you want to test your whole application and therewith the interaction between the parts that you have unit tested beforehand. So you do not import single providers but instead a module, typically the AppModule. You can then override single providers, e.g. if you want to test on an in-memory database instead of an actual one or you want to mock the results of an external API.

    const moduleFixture = await Test.createTestingModule({
          imports: [AppModule],
        }).overrideProvider(DatabaseConnection).useClass(InMemoryDatabaseConnection)
          .overrideProvider(ExternalApiService).useValue(externalApiMock)
          .compile();
        app = moduleFixture.createNestApplication();
        externalApiMock.get.mockReturnValueOnce({data: [...]});
        await app.init();
    

    How to create mocks?

    See this answer.

    0 讨论(0)
提交回复
热议问题