单元测试 Nest JS 过滤器捕获方法

Posted

技术标签:

【中文标题】单元测试 Nest JS 过滤器捕获方法【英文标题】:Unit Test Nest JS Filter Catch Method 【发布时间】:2020-02-21 00:24:07 【问题描述】:

我想为具有 Catch 方法的 Nest JS 过滤器编写单元测试。 发生异常时如何传递/模拟传递的参数。 如何断言logger.error被调用。

Jest 用于单元测试

这是捕捉所有异常的 Nest JS 过滤器代码。


@Catch()
export class AllExceptionsFilter implements ExceptionFilter 
  constructor(private logger: AppLoggerService) 

  catch(exception: any, host: ArgumentsHost) 
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();

    const message = 
      Title: exception.name,
      Type: 'Error',
      Detail: exception.message,
      Status: 'Status',
      Extension: '',
    ;
    this.logger.error(message, '');

    const status =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    response.status(status).send(
      statusCode: status,
      timestamp: new Date().toISOString(),
      path: request.url,
    );
  

我现有的单元测试代码如下,需要在 catch 方法上编写测试。

describe('AllExceptionsFilter', () => 
    let allExceptionsFilter: AllExceptionsFilter;
    let appLoggerService: AppLoggerService;

    beforeEach(async () => 
        const loggerOptions =  appPath: process.cwd() 
        const module: TestingModule = await Test.createTestingModule(
            providers: [AllExceptionsFilter,
                
                    provide: AppLoggerService,
                    useValue: new AppLoggerService(loggerOptions, 'AllExceptionsFilter'),
                ,
            ],
        ).compile();
        allExceptionsFilter = module.get<AllExceptionsFilter>(AllExceptionsFilter);
    );

    it('should be defined', () => 
        expect(allExceptionsFilter).toBeDefined();
    );
);

单元测试的测试覆盖率应该是100%。

【问题讨论】:

【参考方案1】:

您可以在测试所有服务、控制器等时测试过滤器的 catch 方法。无需模拟整个 catch 流程,因为它位于 nest.js 部分。您的测试将如下所示

import  ConfigModule  from '@nestjs/config';
import  Test, TestingModule  from '@nestjs/testing';
import configuration from '../config';
import  IneligibleExceptionFilter  from './ineligible.filter';

describe('IneligibleExceptionFilter', () => 
  let service: IneligibleExceptionFilter;

  beforeEach(async () => 
    const module: TestingModule = await Test.createTestingModule(
      imports: [ConfigModule.forRoot( isGlobal: true, load: [configuration] )],
      providers: [IneligibleExceptionFilter],
    ).compile();

    service = module.get<IneligibleExceptionFilter>(IneligibleExceptionFilter);
  );

  it('should be defined', () => 
    expect(service).toBeDefined();
  );

  describe('catch', () => 
    it('my test1', () => 
      // some logic here
    );
  );
);

【讨论】:

以上是关于单元测试 Nest JS 过滤器捕获方法的主要内容,如果未能解决你的问题,请参考以下文章

Nest.js 在单元测试中无法解析 Mongoose 模型依赖

在 Spring boot 中为 Filter (OncePerRequestFilter) 编写单元测试

在单元测试中捕获调试窗口输出?

Nest JS - 为返回 Observable Axios 响应的函数编写 Jest 测试用例的问题

如何在单元测试中正确捕获 zap logger 输出

严格捕获测试用例以进行单元测试