前言:当前内容仅是对官网的testing做一些调整改动,发现官网的教程不是很适用当前版本v4版本的,估计是没有及时更新。
当前使用版本:【 Strapi: 4.15.5 ;node: v20.5.0 ;yarn: 1.22.21】
- 添加依赖包:
测试用sqlite3就可以了,可以不用mysql
yarn add --dev jest supertest sqlite3
如果后续 testing 提示出现:property ‘client’ of ‘db.config.connection’ as it is undefined.
这里可以是试下添加 better-sqlite3
- 修改配置文件
在package.json添加:
在collectCoverageFrom 里面path前面加 ! 是取反,不包含此路径
"jest": {
"collectCoverage": true,
"testResultsProcessor": "jest-junit",
"testEnvironment": "node",
"testPathIgnorePatterns": [
"/node_modules/",
".tmp",
".cache"
]
},
test 配置读 tests/.env,区分 unit test环境 和 其他环境
"scripts": {
"build": "strapi build",
"develop": "strapi develop",
"start": "strapi start",
"strapi": "strapi",
"test": "ENV_PATH=tests/.env jest --forceExit --detectOpenHandles --coverage --verbose"
}
tsconfig.json:
{
"extends": "@strapi/typescript-utils/tsconfigs/server",
"compilerOptions": {
"outDir": "dist",
"rootDir": "."
},
"include": [
"./",
"./**/*.ts",
"./**/*.js",
"src/**/*.json",
"../../tests/.env"
],
"exclude": [
"node_modules/",
"build/",
"dist/",
".cache/",
"src/admin/",
"src/plugins/**"
]
}
Set up a testing environment
在config/database.ts下面的sqlite配置:
- 创建Strapi实例 Create a Strapi instance
./tests/.env
APP_KEYS=XXX
API_TOKEN_SALT=XXX
ADMIN_JWT_SECRET=XXX
TRANSFER_TOKEN_SALT=XXX
JWT_SECRET=XXXX
DATABASE_CLIENT=sqlite
./tests/helpers/strapi.ts
import Strapi from "@strapi/strapi";
import fs from "fs";
let instance;
async function setupStrapi() {
if (!instance) {
await Strapi({distDir: "./dist"}).load();
instance = strapi;
await instance.server.mount();
}
return instance;
}
async function cleanupStrapi() {
// const dbSettings: any = strapi.config.get("database.connections.default.settings");
const dbSettings: any = strapi.config.get("database");
//close server to release the db-file
await strapi.server.httpServer.close();
// close the connection to the database before deletion
await strapi.db.connection.destroy();
//delete test database after all tests have completed
if (dbSettings && dbSettings.connection && dbSettings.connection.connection && dbSettings.connection.connection.filename) {
const tmpDbFile = dbSettings.connection.connection.filename;
if (fs.existsSync(tmpDbFile)) {
fs.unlinkSync(tmpDbFile);
}
}
}
export {setupStrapi, cleanupStrapi};
./tests/helpers/user.ts
const mockUserData = {
username: "tester",
email: "tester@test.com",
provider: "local",
password: "1234abc",
confirmed: true,
blocked: null,
role: null
};
const createUserWithAuthenticatedRole = async (newUser = {}) => {
const advancedPromise: any = strapi.store({type: "plugin", name: "users-permissions", key: "advanced"});
const advanced: any = await advancedPromise.get();
const defaultRole = await strapi
.query("plugin::users-permissions.role")
.findOne({where: {type: advanced.default_role}});
mockUserData.role = defaultRole.id; // Assign the Authenticated role to the user
const user = await strapi.plugins["users-permissions"].services.user.add({
...mockUserData,
...newUser,
});
return user;
};
/**
* Create user with role Authenticated
* @returns {Object}
*/
const getAuthenticatedUser = async () => {
let user;
user = await strapi.db.query("plugin::users-permissions.user").findOne({
where: {
email: mockUserData.email,
},
populate: {role: true},
});
if (!user) {
user = await createUserWithAuthenticatedRole();
}
// Issue a token for this user - to test the private routes
const jwt = strapi.plugin("users-permissions").service("jwt").issue({
id: user.id,
});
return {
user,
jwt,
};
};
module.exports = {
getAuthenticatedUser,
createUserWithAuthenticatedRole,
};
./tests/app.test.ts
import { setupStrapi, cleanupStrapi } from "./helpers/strapi";
import {expect,it} from "@jest/globals";
beforeAll(async () => {
await setupStrapi();
await grantPrivilege();
});
afterAll(async () => {
await cleanupStrapi();
});
it("strapi is defined",async () => {
expect(strapi).toBeDefined();
});
const authenticatedRolePermissions = {
name: "Authenticated",
description: "Default role given to authenticated user.",
permissions: {
"api::about": {
controllers: {
about: {
find: { enabled: true, policy: "" },
update: { enabled: true, policy: "" },
delete: { enabled: true, policy: "" },
}
}
}
},
};
const grantPrivilege = async (roleID: number = 1) => {
return strapi.plugin("users-permissions").service("role").updateRole(roleID, authenticatedRolePermissions);
};
require('./about/about');
./tests/about/about.ts
这里要先create再call find,不然会提示Unit testing endpoints 403 FORBIDDEN
import {expect,it} from "@jest/globals";
const request = require('supertest');
const {getAuthenticatedUser} = require("../helpers/user");
it("test about", async () => {
const {user, jwt} = await getAuthenticatedUser();
const resp = await request(strapi.server.httpServer)
.put("/api/about").send({
data: {
test01: "https://www.google.com.hk/?gws_rd=ssl"
}
})
.set('accept', 'application/json')
.set('Content-Type', 'application/json')
.set('Authorization', 'Bearer ' + jwt)
.expect(200) // Expect response http code 200
.then((data) => {
expect(data.text).not.toBeNull();
return data.text;
});
await request(strapi.server.httpServer)
.get("/api/about")
.set('accept', 'application/json')
.set('Content-Type', 'application/json')
.set('Authorization', 'Bearer ' + jwt)
.expect(200) // Expect response http code 200
.then((data) => {
expect(data.text).toBe(resp); // expect the response text
});
await request(strapi.server.httpServer)
.delete("/api/about")
.set('accept', 'application/json')
.set('Content-Type', 'application/json')
.set('Authorization', 'Bearer ' + jwt)
.expect(200) // Expect response http code 200
.then((data) => {
expect(data.text).toBe(resp); // expect the response text
});
});
- jest testing
jest
官网参考地址:
https://docs.strapi.io/dev-docs/testing