#Obtaining provider instance from specific module's DI tree

4 messages · Page 1 of 1 (latest)

meager leaf
#

Hey team, a question about testing and DI tree. Given the tested module imports another dynamic module, is there a way to get the instance of the provider exported by that dynamic module?

Here’s my use case:

  • I’ve got a module (say DynamicModule) with a register method that exports a provider (say ExportedService)
  • I have multiple other modules that import and register the module to use ExportedService. Something like:
@Module({
    imports: DynamicModule.register()
})
class ModuleA

@Module({
    imports: DynamicModule.register()
})
class ModuleB
  • This means that ModuleA and ModuleB have different instances of ExportedService

The problem:
I have an E2E test where I need to check ModuleB and get its instance of ExportedService to perform some assertions. The problem is that I cannot find a way of getting that specific instance. I always get ExportedService from ModuleA.

I tried fetching the provider from ModuleB’s DI tree, like below, but then I get Nest could not find ExportedService element (this provider does not exist in the current context)

const app = Test.createTestingModule().compile()
const moduleBContext =  app.select(ModuleB);
const serviceInstance = moduleBContext.get(ExportedService, { strict: true });

And without { strict: true } I get the instance from ModuleA. Is there any way around this?

shell jewel
#

The problem is that with select, you can only retrieve direct providers from that module, not transitive ones (i.e. those from imported modules)

#

To get around it, you could register a useExisting provider in ModuleB to refer to the dynamic module's provider

meager leaf
#

thanks for getting back to me @shell jewel!
and what if useExisting is not an option since I really need a fresh instance of the dynamic module's provider?
(why: that provider needs to be created with different constructor props in ModuleA and ModuleB)

To be honest, I found another ugly workaround that bypasses the DI mechanism completely, by spying on ExportedService.prototype. It does the job in my test, but I wanted to understand if there's a more proper way that I can't think of