单元和集成测试指南
¥Unit and integration testing guide
Page summary:
Testing relies on Jest and Supertest with an in-memory SQLite database, a patched Strapi test harness that also supports TypeScript configuration files, and helpers that automatically register the
/helloroute and authenticated role during setup.
本指南提供了在 Strapi 5 应用中配置 Jest 的实践方法,包括模拟 Strapi 对象以进行单元测试插件代码,以及使用 超测 端到端测试 REST 端点。
¥The present guide provides a hands-on approach to configuring Jest in a Strapi 5 application, mocking the Strapi object for unit testing plugin code, and using Supertest to test REST endpoints end to end.
本指南旨在重新创建 strapi-unit-testing-examples CodeSandbox 链接中提供的最小测试套件。
¥The guide aims to recreate the minimal test suite available in the strapi-unit-testing-examples CodeSandbox link.
如果你在 Windows 上使用 SQLite 数据库,则本指南将不起作用,因为 Windows 会锁定 SQLite 文件。
¥The present guide will not work if you are on Windows using the SQLite database due to how Windows locks the SQLite file.
安装工具
¥Install tools
我们将首先安装测试工具,添加运行测试的命令,并配置 Jest。
¥We'll first install test tools, add a command to run our tests, and configure Jest.
-
通过在终端中运行以下命令安装 Jest 和 Supertest:
¥Install Jest and Supertest by running the following command in a terminal:
- Yarn
- NPM
```bash
yarn add jest supertest --dev
```
```bash
npm install jest supertest --save-dev
```
* `Jest` provides the test runner and assertion utilities.
* `Supertest` allows you to test all the `api` routes as they were instances of <ExternalLink to="https://nodejs.cn/api/http.html#class-httpserver" text="http.Server"/>.
* Add a `test` command to the `scripts` section so it looks as follows:
"scripts": {
"build": "strapi build",
"console": "strapi console",
"deploy": "strapi deploy",
"dev": "strapi develop",
"develop": "strapi develop",
"seed:example": "node ./scripts/seed.js",
"start": "strapi start",
"strapi": "strapi",
"upgrade": "npx @strapi/upgrade latest",
"upgrade:dry": "npx @strapi/upgrade latest --dry",
"test": "jest --forceExit --detectOpenHandles"
},
* Configure Jest at the bottom of the file to ignore Strapi build artifacts and to map any root-level modules you import from tests:
"jest": {
"testPathIgnorePatterns": [
"/node_modules/",
".tmp",
".cache"
],
"testEnvironment": "node",
"moduleNameMapper": {
"^/create-service$": "<rootDir>/create-service"
}
}
模拟 Strapi 进行插件单元测试
¥Mock Strapi for plugin unit tests
纯单元测试非常适合 Strapi 插件,因为它们允许你在不启动 Strapi 服务器的情况下验证控制器和服务逻辑。使用 Jest 的 mocking
¥Pure unit tests are ideal for Strapi plugins because they let you validate controller and service logic without starting a Strapi server. Use Jest's mocking
用于重新创建 Strapi 对象的各个部分以及代码所依赖的任何请求上下文的实用程序。
¥utilities to recreate just the parts of the Strapi object and any request context that your code relies on.
控制器示例
¥Controller example
创建一个测试文件,例如 ./tests/todo-controller.test.js,使用模拟的 Strapi 对象实例化你的控制器,并验证控制器执行的每个调用:
¥Create a test file such as ./tests/todo-controller.test.js that instantiates your controller with a mocked Strapi object and verifies every call the controller performs:
const todoController = require('./todo-controller');
describe('Todo controller', () => {
let strapi;
beforeEach(() => {
strapi = {
plugin: jest.fn().mockReturnValue({
service: jest.fn().mockReturnValue({
create: jest.fn().mockReturnValue({
data: {
name: 'test',
status: false,
},
}),
complete: jest.fn().mockReturnValue({
data: {
id: 1,
status: true,
},
}),
}),
}),
};
});
it('creates a todo item', async () => {
const ctx = {
request: {
body: {
name: 'test',
},
},
body: null,
};
await todoController({ strapi }).index(ctx);
expect(ctx.body).toBe('created');
expect(strapi.plugin('todo').service('create').create).toHaveBeenCalledTimes(1);
});
it('completes a todo item', async () => {
const ctx = {
request: {
body: {
id: 1,
},
},
body: null,
};
await todoController({ strapi }).complete(ctx);
expect(ctx.body).toBe('todo completed');
expect(strapi.plugin('todo').service('complete').complete).toHaveBeenCalledTimes(1);
});
});
beforeEach 钩子会重建模拟,因此每个测试都从一个干净的 Strapi 实例开始。每个测试都会准备控制器期望的 ctx 请求对象,调用控制器函数,并断言响应和与 Strapi 服务的交互。
¥The beforeEach hook rebuilds the mock so every test starts with a clean Strapi instance. Each test prepares the ctx request object that the controller expects, calls the controller function, and asserts both the response and the interactions with Strapi services.