How to configure middleware in e2e test in nestjs
Asked Answered
S

3

8

In real app, we write:

export class AppModule implements NestModule {
  constructor() {}

  configure(consumer: MiddlewareConsumer) {
    consumer.apply(JwtExtractionMiddleware).forRoutes({
      path: 'graphql',
      method: RequestMethod.ALL,
    });
  }
}

In e2e test, I do something like this:

const module = await Test.createTestingModule({
  imports: [ GraphQLModule.forRoot(e2eGqlConfig) ],
  providers: [ PubUserResolver ],
}).compile();
app = await module.createNestApplication().init();

So how can I specific middleware in e2e test?

Symbolize answered 13/9, 2018 at 14:18 Comment(1)
Did you figure out how to use middle-ware in tests ?Warring
O
15

Maybe try to create a specific TestModule class only for e2e and provide it to the createTestingModule?

@Module({
  imports: [ GraphQLModule.forRoot(e2eGqlConfig) ],
  providers: [ PubUserResolver ],
})
export class TestModule implements NestModule {
  constructor() {}

  configure(consumer: MiddlewareConsumer) {
    consumer.apply(JwtExtractionMiddleware).forRoutes({
      path: 'graphql',
      method: RequestMethod.ALL,
    });
  }
}

And then in e2e:

const module = await Test.createTestingModule({
  imports: [TestModule]
}).compile();
app = await module.createNestApplication().init();

I had similar problem, I needed to attach global middlewares. There is no info on the Internet about that as well, but by chance I've found the solution. Maybe someone will be looking for it, so here it is:

To use global middleware in e2e in NestJS:

Firstly create the app, but don't init it. Only compile:

const app = Test
  .createTestingModule({ imports: [AppModule] })
  .compile()
  .createNestApplication();

After that you can add all your global middlewares:

app.enableCors();
app.use(json());
app.use(formDataMiddleware(config));

Now init the app and that's it:

await app.init();
Opinicus answered 18/11, 2018 at 9:7 Comment(6)
Tried your solution, but can't get middle-ware attached. Did you had a chance to try it (also first option)?Warring
As I've written above, I am attaching all the middlewares in e2e tests between createNestApplication() and init() and it works.Opinicus
@Opinicus tried your solution, the middleware doesn't seem to have been applied.Threesquare
I also didn't get a Middleware class to work... With a functional middleware it worked, see docs.nestjs.com/middlewareAntiworld
@MaximilianFriedmann For Class, you can make it work like app.use(new SomeMiddleware().use);Siple
@Opinicus You saved my day! :-)Protactinium
H
4

You'll need to put app.use(new AuthMiddleware().use); before app.init().

describe('Module E2E', () => {
  const mockedTest = {
    create: jest.fn().mockImplementation((t) => Promise.resolve(t)),
  };

  let app: INestApplication;

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [
        ConfigModule.forRoot({
          load: [configuration],
        }),
      ],
      controllers: [TestController],
      providers: [
        TestService, // the service contains a MySQL Model
        {
          provide: getModelToken(Test), // Test is the name of Model
          useValue: mockedTest,
        },
      ],
    }).compile();

    app = moduleRef.createNestApplication();
    app.use(new AuthMiddleware().use); // auth middleware
    await app.init();
  });
});
Hemato answered 10/8, 2020 at 8:39 Comment(0)
B
0

Additional to previous answer about use class middleware.

this app.use(new AuthMiddleware().use); is not working for me because use function cannot find this in class

So, need to use bind function

const middleware = new AuthMiddleware()
app.use(middleware.use.bind(middleware));
Beta answered 29/6, 2023 at 16:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.