William Gao
William Gao

Reputation: 73

How to do unit testing for guard in nest?

I'v done unit testing for controllers and services like this:

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
 let catsController: CatsController;
 let catsService: CatsService;

 beforeEach(() => {
   catsService = new CatsService();
   catsController = new CatsController(catsService);
 });

 describe('findAll', () => {
   it('should return an array of cats', async () => {
     const result = ['test'];
     jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

     expect(await catsController.findAll()).toBe(result);
   });
 });
});

but I hava a global guard, this guard is independent of any controller or service, I do not know how to write the .spec file. PLZ

Upvotes: 5

Views: 6063

Answers (1)

Micael Levi
Micael Levi

Reputation: 6695

I have the following guard

import { ExecutionContext, Injectable, CanActivate, UnauthorizedException } from '@nestjs/common';
import type { Request } from 'express';

@Injectable()
export class AuthenticatedGuard implements CanActivate {
  canActivate(context: ExecutionContext): true | never {
    const req = context.switchToHttp().getRequest<Request>();
    const isAuthenticated = req.isAuthenticated();
    if (!isAuthenticated) {
      throw new UnauthorizedException();
    }
    return isAuthenticated;
  }
}

and then my authenticated.guard.spec.ts is:

import { createMock } from '@golevelup/ts-jest';
import { ExecutionContext, UnauthorizedException } from '@nestjs/common';

import { AuthenticatedGuard } from '@/common/guards';

describe('AuthenticatedGuard', () => {
  let authenticatedGuard: AuthenticatedGuard;

  beforeEach(() => {
    authenticatedGuard = new AuthenticatedGuard();
  });

  it('should be defined', () => {
    expect(authenticatedGuard).toBeDefined();
  });

  describe('canActivate', () => {
    it('should return true when user is authenticated', () => {
      const mockContext = createMock<ExecutionContext>();
      mockContext.switchToHttp().getRequest.mockReturnValue({
        // method attached to `req` instance by Passport lib
        isAuthenticated: () => true,
      });

      const canActivate = authenticatedGuard.canActivate(mockContext);

      expect(canActivate).toBe(true);
    });

    it('should thrown an Unauthorized (HTTP 401) error when user is not authenticated', () => {
      const mockContext = createMock<ExecutionContext>();
      mockContext.switchToHttp().getRequest.mockReturnValue({
        // method attached to `req` instance by Passport lib
        isAuthenticated: () => false,
      });

      const callCanActivate = () => authenticatedGuard.canActivate(mockContext);

      expect(callCanActivate).toThrowError(UnauthorizedException);
    });
  });
});

Inspired by jmcdo29/testing-nestjs

Upvotes: 13

Related Questions