RemeJuan
RemeJuan

Reputation: 863

Testing Class with @Injectable Scope / @Inject(REQUEST) NestJS

I have set up a MongooseConfigService to allow us to dynamically switch out the connection string for certain requests and am trying to get the tests set up correctly.

@Injectable({scope: Scope.REQUEST})
export class MongooseConfigService implements MongooseOptionsFactory {
  constructor(
    @Inject(REQUEST) private readonly request: Request) {
  }

I am however having trouble providing request to the test context.

  let service: Promise<MongooseConfigService>;
  
  beforeEach(async () => {
    const req = new JestRequest();
    
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        MongooseConfigService,
        {
          provide: getModelToken(REQUEST),
          inject: [REQUEST],
          useFactory: () => ({
            request: req,
          }),
        },
      ],
    }).compile();
    
    service = module.resolve<MongooseConfigService>(MongooseConfigService);
  });

This is as far as I have gotten, have tried it without the inject and with/without useValue, however this.request remains undefined when trying to run the tests.

TIA

Upvotes: 11

Views: 6005

Answers (2)

undertakingyou
undertakingyou

Reputation: 149

I faced the same issue today and found a slightly easier method.

let service: MongooseConfigService;

beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
        providers: [
            MongooseConfigService, // or whatever your service is
            {
                provide: REQUEST,
                useValue: { user: { idpId: 'idpId' } },
            },
        ],
    }).compile();
    service = await module.resolve(MongooseConfigService);
});

In my case I only needed to retrieve certain user details from the request, so this was easy. You could easily substitute the useValue here with the JestRequest noted in the other answer. My experience is that you are often already using multiple providers in this way, which makes this quite easy to add as just another provider.

Upvotes: -1

adamC
adamC

Reputation: 265

maybe try to instantiate the testing module with only import: [appModule] and then try to get the service. also, try to use overrideprovider and usevalue like this:

let service: Promise<MongooseConfigService>;
  
  beforeEach(async () => {
    const req = new JestRequest();
    
    const module: TestingModule = await Test.createTestingModule({
      imports: [appModule]
    }).overrideProvider(REQUEST)
      .useValue(req)
      .compile();
    
    service = module.resolve<MongooseConfigService>(MongooseConfigService);
  });

Upvotes: 11

Related Questions