nestjs / nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
https://nestjs.com
MIT License
66.89k stars 7.56k forks source link

overrideInterceptor being ignored #3628

Closed bryanmytko closed 4 years ago

bryanmytko commented 4 years ago

Bug Report

Current behavior

I have an endpoint that accepts an uploaded file. This is handled via the FileInterceptor, passing s3 credentials to multer. Everything works fine when testing the endpoint via Postman.

I'm trying to test this endpoint in an e2e test, but since I don't want to be uploading files to s3 every time I run the tests, especially on CI, I'm trying to circumvent the FileInterceptor and just throw a dummy object to the logic that handles the uploaded file.

I'm using overrideInterceptor in my test, but it seems to do nothing. The interceptor is still being hit and the error thrown is related to S3 access, which is only expected without the override, since I don't have AWS credentials set up for the test environment.

Input Code

guides.controller.ts

  @Post()
  @HttpCode(201)
  @UseInterceptors(FileInterceptor('file', multerAudioConfig))
  create(@UploadedFile() file: any, @Body() createGuidesDto: GuidesDto) {
    console.log('FILE: ', file);
    const audioDto: AudiosDto = { url: file.location };
    const guideDto: GuidesDto = { ...createGuidesDto, audio: audioDto };

    return this.guideRepository.createGuide(guideDto);
  }

guides.e2e-spec.ts

const audio = `${__dirname}/test-files/test.mp3`;

beforeAll(async () => {
    const fileInterceptor = { url: 'asdfasdfasd' };

    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule, TypeOrmModule.forRoot()],
      providers: [
        GuideRepository,
        {
          provide: getRepositoryToken(Guide),
          useClass: GuideRepository,
        },
      ],
    })
    .overrideInterceptor(FileInterceptor)
    .useValue(fileInterceptor)
    .compile();

    app = moduleFixture.createNestApplication();
    await app.init();
    guideRepository = moduleFixture.get<GuideRepository>(GuideRepository);
  });

[...]

describe('POST /guides', () => {
      it('returns 201 Created', () => {
        return request(app.getHttpServer())
          .post('/guides')
          .attach('file', audio)
          .field('title', 'foo')
          .expect(201);
      });

[...]

Expected behavior

I'm expecting the interceptor to be overridden with my defined object.

Environment


Nest version: 6.10.10 (@nestjs/core)
(Though `nest --version` says 6.11.1 ??)

For Tooling issues:
- Node version: v12.4.0
- Platform:  Mac

Others:
🤷‍♀ using yarn
kamilmysliwiec commented 4 years ago

Notice that FileInterceptor is a class, while FileInterceptor('file', multerAudioConfig) returns a mixin class. FileInterceptor !== returned mixin. To override a mixin, store it as a variable:

export const AudioFileInterceptor = FileInterceptor('file', multerAudioConfig);

And then, use AudioFileInterceptor in your e2e tests.

Please, use our Discord channel (support) for such questions. We are using GitHub to track bugs, feature requests, and potential improvements.

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.