Search code examples
unit-testingjestjsnestjs

NestJS: How can I mock ExecutionContext in canActivate


I am having trouble in mocking ExecutionContext in Guard middleware.

Here's my RoleGuard extends JwtGuard

@Injectable()
export class RoleGuard extends JwtAuthGuard {
 ...
 async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const params = request.params;

    ...
 }
}

This is what I am trying on my unit test.

let context: ExecutionContext = jest.genMockFromModule('@nestjs/common');
  
context.switchToHttp = jest.fn().mockResolvedValue({
  getRequest: () => ({
   originalUrl: '/',
   method: 'GET',
   params: undefined,
   query: undefined,
   body: undefined,
  }),
  getResponse: () => ({
    statusCode: 200,
  }),
});
    
jest.spyOn(context.switchToHttp(), 'getRequest').mockImplementation(() => {
 return Promise.resolve(null);
});

And I am getting this kind of error.

Cannot spy the getRequest property because it is not a function; undefined given instead

I would like you to suggest any other way to mock context. Thank you.


Solution

  • Please check this library https://www.npmjs.com/package/@golevelup/ts-jest

    Then you could mock ExecutionContext as following.

    import { createMock } from '@golevelup/ts-jest';
    import { ExecutionContext } from '@nestjs/common';
     
    describe('Mocked Execution Context', () => {
      it('should have a fully mocked Execution Context', () => {
        const mockExecutionContext = createMock<ExecutionContext>();
        expect(mockExecutionContext.switchToHttp()).toBeDefined();
    
        ...
    
      });
    });
    

    Hope it helps