liaoliaots/nestjs-redis

Testing: Mocking for App Module not working

anomaly44 opened this issue · 3 comments

Expected Behavior

Mocking the Redis provider when running an e2e test should provide a mocked redis instance that does not try connection to a Redis server.

app.module.ts:

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [configuration],
      isGlobal: true,
    }),
    RedisModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (
        configService: ConfigService,
      ): Promise<RedisModuleOptions> => {
        const config = configService.get('redis');  // this also has namespace 'sipUsers'
        return {
          config,
        };
      },
    }),
    KamailioApiModule,
  ],
  controllers: [AppController],
  providers: [
    AppService,
  ],
})

app.e2e-spec.ts

const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
      providers: [
        {
          provide: getRedisToken('sipUsers'),
          useValue: mockedRedisService,
        },
      ],
    })

Current Behavior

Running this test gives me this error, meaning the mock for the app module is not working:
[Nest] 75665 - 18/10/2022, 17:35:36 ERROR [RedisModule] sipUsers: connect ECONNREFUSED 127.0.0.1:6379

Context

I also run a unit test for the service that uses the Redis module. Here the mock works perfectly.

Redis injected like this in my service:

export class KamailioApiService {
  private kamailioApiUrl = this.configService.get('kamailioApi.url');
  private kamailioApiKey = this.configService.get('kamailioApi.apiKey');
  constructor(
    private http: HttpService,
    private configService: ConfigService,
    @InjectRedis('sipUsers') private readonly redis: Redis,
  ) {}
...

The mock:

const module: TestingModule = await Test.createTestingModule({
      providers: [
        KamailioApiService,
        {
          provide: ConfigService,
          useValue: mockedConfigService,
        },
        {
          provide: getRedisToken('sipUsers'),
          useValue: mockedRedisService,
        },
        loggerProvider(KamailioApiService.name),
      ],
      imports: [HttpModule], // this is just a test to make tests run, dont know if we should mock this here already
    }).compile();

So it's weird to me that it doesnt work when mocking it for the root App, But I cant figure out why since I mock other services in the same way for both my unit and e2e tests.

  • Version used:
  • NestJS version: 8
  • Node.js version: 16

anyone have any idea?

I have the same issue with the latest version of this library. The only references to getRedisToken are in docs and test code. It's not actually used by the modules being created. We cannot override a provider that is never provided.

@liaoliaots this seems like a bug that needs to be addressed.

One solution that does work is to use ioredis-mock. Adding the line below to my test files results in successfully mocking the Redis client:

jest.mock('ioredis', () => jest.requireActual('ioredis-mock'));