I want to mock JWT Authentication in my NestJS e2e (integration) tests. I use injected token data in my business logic, and I don't want to insert credentials on my test code.
I implemented JWT authentication as per the Nest authentication docs. I use a decorator (similar) to the @User
decorator in the examples, and use information on the User object in my business logic.
@Post()
async myPostEndpoint(@Body() body: PostBody, @User() user: MyUser){
// do stuff using user properties
}
When testing my application using supertest as indicated in the Nest testing docs, I don't want to make a real authentication request, as I would need to persist credentials in my version control system.
I expected to be able to override providers to return a test user. But couldn't figure it out.
I tried overriding the AuthService
's validateClient
and login
to return a default user using overrideProvider + useClass/useFactory/useValue
as indicated in the Nest testing docs. I also tried overriding methods in JwtStrategy
and LocalStrategy
, but the requests still return 401 - Unauthorized.
In your overrideGuard(AuthGuard('jwt')).useValue()
you can add functionality to your canActivate()
function to look like the following:
canActivate (context: ExecutionContext) => {
const req = context.switchToHttp().getRequest();
req.user = myCustomUserObject;
return true;
}
Where myCustomUserObject
is the expected value of req.user
for the server to handle.
For people using GraphQL, this is what I did:
const module: TestingModule = await Test.createTestingModule({
imports: [AppModule],
})
.overrideGuard(JwtAuthGuard)
.useValue({
canActivate: (context: ExecutionContext) => {
const ctx = GqlExecutionContext.create(context)
ctx.getContext().req.user = { user_id: "abc123" } // Your user object
return true
},
})
.compile()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With