I'm working on e2e test for Nestjs app, one of the modules is using https://github.com/deligenius/aws-sdk-v3-nest module. I'm stuck with mocking it.
I can't figure out how to mock S3 client injected in attachment module. When running test, it actually use real S3 client.
Here what I have so far.
// app.module
@Module({
imports: [
AttachmentsModule,
],
controllers: [],
providers: [],
})
export class AppModule {
}
// attachment module
@Module({
controllers: [],
providers: [
S3fileService,
],
imports: [
AwsSdkModule.registerAsync({
clientType: S3Client,
imports: [ConfigModule],
useFactory: async (configService: ConfigService<EnvConfigs, true>) => {
const awsConfigs = configService.get('awsConfigs', { infer: true });
return new S3Client({
region: awsConfigs.region,
});
},
inject: [ConfigService],
}),
],
exports: [S3fileService],
})
export class AttachmentsModule {}
// S3fileService service
@Injectable()
export class S3fileService {
constructor(
@InjectAws(S3Client) private readonly s3: S3Client, // I want to mock this S3Client
) {
console.log(s3);// during test this is real s3 instance
}
}
// my test
import { S3Client } from '@aws-sdk/client-s3';
import { mockClient } from 'aws-sdk-client-mock';
const s3Mock = mockClient(S3Client);
describe('InvoicesController (e2e)', () => {
let app: INestApplication;
beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
providers: [/// this is not working
{
provide: S3Client,
useValue: s3Mock,
},
],
})
.overrideProvider(S3Client) // this is not working
.useValue(s3Mock)
.compile();
app = moduleFixture.createNestApplication();
await app.init();
});
});
Turns out I need to use correct DI token. I have imported S3Client in service like @InjectAws(S3Client) private readonly s3: S3Client and under the hood it generating token something like AWS_SDK_V3_MODULE#S3Client#. o Im not sure this is correct way to do it , but it works!
.overrideProvider('AWS_SDK_V3_MODULE#S3Client#') // this is working
.useValue(s3Mock)