测试是确保软件质量和可维护性的关键组成部分。在 Nest.js 中,我们可以使用 Jest 作为默认的测试框架来进行单元测试和集成测试。本文将详细介绍如何在 Nest.js 中进行测试,包括基本配置、单元测试、集成测试的编写及示例。
Jest 是一个功能强大且易于使用的 JavaScript 测试框架,提供了丰富的功能,包括:
Nest.js 项目默认使用 Jest 进行测试,因此你可以直接使用它。如果你的项目还没有 Jest,可以通过以下命令安装:
npm install --save-dev jest @nestjs/testing ts-jest @types/jest
单元测试的目的是验证单个组件的功能,确保其在不同输入下的行为符合预期。
假设我们有一个简单的用户服务:
3.1.1 创建用户服务
在 users.service.ts
中:
import { Injectable } from '@nestjs/common';
@Injectable()
export class UsersService {
private users = [];
create(user: { name: string; email: string }) {
this.users.push(user);
return user;
}
findAll() {
return this.users;
}
}
3.1.2 创建单元测试
在 users.service.spec.ts
中:
import { Test, TestingModule } from '@nestjs/testing';
import { UsersService } from './users.service';
describe('UsersService', () => {
let service: UsersService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UsersService],
}).compile();
service = module.get<UsersService>(UsersService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
it('should create a user', () => {
const user = { name: 'John Doe', email: 'john@example.com' };
expect(service.create(user)).toEqual(user);
});
it('should find all users', () => {
const user1 = { name: 'John Doe', email: 'john@example.com' };
const user2 = { name: 'Jane Doe', email: 'jane@example.com' };
service.create(user1);
service.create(user2);
expect(service.findAll()).toEqual([user1, user2]);
});
});
运行以下命令执行测试:
npm run test
你应该会看到所有测试通过的输出。
集成测试的目的是验证多个组件的协作是否正常。
假设我们有一个用户控制器来处理 HTTP 请求:
4.1.1 创建用户控制器
在 users.controller.ts
中:
import { Controller, Post, Body, Get } from '@nestjs/common';
import { UsersService } from './users.service';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Post()
create(@Body() createUserDto: { name: string; email: string }) {
return this.usersService.create(createUserDto);
}
@Get()
findAll() {
return this.usersService.findAll();
}
}
4.1.2 创建集成测试
在 users.controller.spec.ts
中:
import { Test, TestingModule } from '@nestjs/testing';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
describe('UsersController', () => {
let controller: UsersController;
let service: UsersService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UsersController],
providers: [UsersService],
}).compile();
controller = module.get<UsersController>(UsersController);
service = module.get<UsersService>(UsersService);
});
it('should create a user', () => {
const user = { name: 'John Doe', email: 'john@example.com' };
jest.spyOn(service, 'create').mockImplementation(() => user);
expect(controller.create(user)).toEqual(user);
});
it('should find all users', () => {
const user1 = { name: 'John Doe', email: 'john@example.com' };
const user2 = { name: 'Jane Doe', email: 'jane@example.com' };
jest.spyOn(service, 'findAll').mockImplementation(() => [user1, user2]);
expect(controller.findAll()).toEqual([user1, user2]);
});
});
在测试中,我们可以使用 Jest 的 jest.spyOn()
方法来模拟服务的方法。这在集成测试中尤其有用,以确保我们可以控制依赖的行为。
对于 HTTP 请求的测试,我们可以使用 Supertest 来模拟 HTTP 请求。
npm install --save-dev supertest
在 app.e2e-spec.ts
中编写端到端测试:
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
describe('Users (e2e)', () => {
let app: INestApplication;
beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/users (POST)', () => {
return request(app.getHttpServer())
.post('/users')
.send({ name: 'John Doe', email: 'john@example.com' })
.expect(201)
.expect(({ body }) => {
expect(body).toEqual({
name: 'John Doe',
email: 'john@example.com',
});
});
});
afterAll(async () => {
await app.close();
});
});
在运行测试时,Jest 也支持生成代码覆盖率报告。可以通过以下命令生成覆盖率报告:
npm run test -- --coverage
在本文中,我们详细介绍了如何在 Nest.js 中使用 Jest 进行单元测试和集成测试。我们涵盖了以下内容:
通过实施测试,我们可以确保代码的质量和稳定性,使维护和扩展变得更加简单和安全。Nest.js 提供的测试支持使得测试变得简单而直观,为开发者提供了强大的工具来构建高质量的应用程序。