测试

测试

自动测试是功能齐全的软件产品的重要组成部分。至少要覆盖系统中最敏感的部分非常关键。为了实现这一目标,我们生成了一组不同的测试,如集成测试,单元测试,e2e测试等。Nest提供了许多测试实用程序,可以改善测试体验。

通常,您可以使用您喜欢使用的任何测试框架。我们不强制执行工具,选择符合您要求的任何工具。主要的Nest应用程序启动程序与Jest框架集成,以减少开始编写测试时的开销,但是,您仍然可以轻松地删除它并使用任何其他工具。

安装

首先,我们需要安装所需的包:

$ npm i --save-dev @nestjs/testing

单元测试

在下面的例子中,我们有两个不同的类,CatsControllerCatsService分别。如前所述,Jest被用作完善的测试框架。该框架的行为类似于测试运行器,并且还提供断言函数和测试双精度实用程序,可以帮助进行模拟,间谍等。一旦调用它,我们就会手动强制执行catsService.findAll()返回result变量的方法。多亏了这一点,我们可以测试是否catsController.findAll()返回预期结果。

cats.controller.spec.ts

JS

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 } } }

提示将测试文件保存在测试类附近。测试文件应该有一个.spec.test后缀。

到目前为止,我们没有使用任何现有的Nest测试实用程序。由于我们手动处理实例化测试类,因此上面的测试套件与Nest无关。这种类型的测试称为隔离测试

测试工具

@nestjs/testing软件包为我们提供了一组可以促进测试过程的实用程序。让我们重写前面的例子,但现在,使用公开的Test类。

cats.controller.spec.ts

JS

import { Test } from '@nestjs/testing'; import { CatsController } from './cats.controller'; import { CatsService } from './cats.service'; describe('CatsController', () => { let catsController: CatsController; let catsService: CatsService; beforeEach(async () => { const module = await Test.createTestingModule{ controllers: [CatsController], providers: [CatsService], }).compile( catsService = module.get<CatsService>(CatsService catsController = module.get<CatsController>(CatsController } 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 } } }

Testclass有一个createTestingModule()方法,它接受模块元数据(与@Module()decorator中传递的对象相同的对象)作为参数。这个方法创建了一个TestingModule实例,该实例又提供了一些方法,但是当涉及单元测试时,它们中只有一个是有用的compile()。此函数是异步的,因此必须等待它。编译模块后,您可以使用get()方法检索任何实例。

为了模拟真实实例,您可以使用自定义提供程序覆盖现有提供程序。

端到端测试

当应用程序增长时,很难手动测试每个API端点的行为。端到端测试有助于我们确保一切正常运行并符合项目要求。要执行e2e测试,我们使用与单元测试相同的配置,但另外,我们利用允许模拟HTTP请求的超级库。

cats.e2e-spec.ts

JS

import * as request from 'supertest'; import { Test } from '@nestjs/testing'; import { CatsModule } from '../../src/cats/cats.module'; import { CatsService } from '../../src/cats/cats.service'; import { INestApplication } from '@nestjs/common'; describe('Cats', () => { let app: INestApplication; let catsService = { findAll: () => ['test'] }; beforeAll(async () => { const module = await Test.createTestingModule{ imports: [CatsModule], }) .overrideProvider(CatsService) .useValue(catsService) .compile( app = module.createNestApplication( await app.init( } it(`/GET cats`, () => { return request(app.getHttpServer()) .get('/cats') .expect(200) .expect{ data: catsService.findAll(), } } afterAll(async () => { await app.close( } }

提示将您的e2e测试文件保留在e2e目录中。测试文件应该有一个.e2e-spec.e2e-test后缀。

cats.e2e-spec.ts测试文件包含单个HTTP端点试验(/cats)。我们使用app.getHttpServer()方法来获取在Nest应用程序的后台运行的底层HTTP服务器。请注意,TestingModule实例提供了一个overrideProvider()方法,因此我们可以覆盖由导入的模块声明的现有提供程序。另外,我们可以依次覆盖使用相应的方法卫士,拦截器,过滤器和管道,overrideGuard()overrideInterceptor()overrideFilter(),和overridePipe()分别。

已编译的模块有几种方法,如下表所述:

createNestInstance()基于给定模块创建Nest实例(返回INestApplication)。请注意,必须使用init()方法手动初始化应用程序。
createNestMicroservice()基于给定模块创建Nest微服务实例(返回INestMicroservice)。
get()检索应用程序上下文中可用的控制器或提供程序的实例(包括警卫,过滤器等)。
select()例如,浏览模块树,从所选模块中提取特定实例(与启用的严格模式一起使用)。