#Testing controller route that uses param decorator

14 messages · Page 1 of 1 (latest)

rocky sandal
#

Hello! I'm writing a unit test for a controller with a route that uses @Sesson() param decorator. I found a thread similar to what I was searching for, but it ended on declaring a separate variable. https://discord.com/channels/520622812742811698/1137991620491489290
I did so:

import { createParamDecorator, type ExecutionContext } from "@nestjs/common";

export const sessionFactory = (data: unknown, ctx: ExecutionContext) => {
  const request = ctx.switchToHttp().getRequest();
  return request.session;
};

export const Session = createParamDecorator(sessionFactory);

And then I use it in the params:

@TsRestHandler(c.quizzes.createQuiz)
@UseGuards(new AuthGuard())
async createQuiz(@Session() session: SessionContainer) {
  return tsRestHandler(c.quizzes.createQuiz, async ({ body }) => {
    const userId = session.getUserId();
    const quiz = await this.quizzesService.create(body, userId);

    return {
      status: 201,
      body: quiz,
    };
  });
}

I assume that in order to unit test the controller I have to mock the @Session decorator, but how do I do so. Should I mock the module using jest.mock? If yes, then what should I mock - the decorator itself or rather the session factory?

faint lava
#

You wouldn't mock the decorator if it's a unit test (in my opinion). You'd call the controller method directly and pass in the proper parameters to the method

rocky sandal
#

The thing is that this decorator is part of whole setup of supertokens (auth provider). This would require me to have an instance of supertokens running in the background then, which is no longer an unit test if I understand correctly

#

Integration with supertokens is mostly DIY, they provide the middleware which attaches session

#

As well as the session verification funtion

#

But this requires a running instance of ST for the sake of tests

faint lava
rocky sandal
faint lava
#

I said you wouldn't mock the decorator itself. You can pass in whatever you want to the controller directly for a unit test (like a mock object of what the session looks like) so long as it adheres to the interface

rocky sandal
#

Alright, that makes sense now. I misunderstood what you meant at first.
Also, is it common to mock auth guards for the sake of tests?
And one more thing - is it a good idea to provide a mock for the service dependency?

faint lava
#

Mock whatever is dependent that your aren't testing: at least in unit tests. Auth guard and similar depends on what kind of test

rocky sandal
#

Thank you for the help! I think I'll manage to go from here

full vale
#

You should ask yourself if it's worth unit testing a controller considering its more of a humble object. You can make sure that it works by just hitting it with a http request imo

faint lava
#

That's a great point as well. Often times controllers funny have much logic to test directly