(@halsp/testing)
单元测试 安装 @halsp/testing
以添加单元测试功能
@halsp/testing
内建了对多种运行环境的单元测试支持
Startup
增加了以下功能
setContext
函数,用于设置测试的请求Context
或Request
keepThrow
函数,调用之后,中间件如果抛出未处理错误,那么框架将不处理这个错误(默认 halsp 会处理错误,并修改状态码为 500)test
函数,开始根据请求执行已添加中间件expect
函数,用于测试断言expectError
函数,用于断言错误
import { Startup } from "@halsp/core";
import "@halsp/testing";
new Startup()
.use(async (ctx, next) => {
ctx.setBody("test");
await next();
})
.expect((res) => {
expect(res.body).toBe("test");
})
.test();
设置 Cotnext 并且把未处理的错误抛出
import { Startup } from "@halsp/core";
import "@halsp/testing";
it("should xxx", async () => {
new Startup()
.expect((res) => {
expect(res.body).toBe("test");
})
.keepThrow()
.setContext(new Context())
.use(() => {
ctx.setBody("test");
await next();
})
.test();
});
断言有未处理错误
import { Startup } from "@halsp/core";
import "@halsp/testing";
it("should xxx", async () => {
new Startup()
.expectError((err) => {
expect(err.message).toBe("err");
})
.keepThrow()
.use(() => {
throw new Error("err");
})
.test();
});
Native
@halsp/testing
已内置对 supertest
的支持
需要单独安装 supertest
npm install supertest -D
调用 startup.nativeTest()
会返回 supertest
实例
import { Startup } from "@halsp/core";
import "@halsp/native";
import "@halsp/testing";
it("should xxx", async () => {
new Startup()
.useNative()
.keepThrow()
.use((ctx) => {
ctx.ok({
method: ctx.req.method,
path: ctx.req.path,
});
})
.nativeTest()
.get("/url")
.expect(200, {
method: "GET",
path: "url",
});
});
WARNING
startup.setContext
不支持 native
Response
Response 新增 expect
函数,用于断言请求结果
有下面几种使用方式
expect(status: number): this;
expect(status: number, body: any): this;
expect(checker: (res: Response) => void): this;
expect(body: any): this;
如
import "@halsp/testing";
import "@halsp/http";
import { Startup } from "@halsp/core";
new Startup()
.useHttp()
.use(async (ctx, next) => {
ctx.ok("body-ok");
await next();
})
.expect((res) =>
res
.expect(200)
.expect(200, "body-ok")
.expect("body-ok")
.expect((res) => {
expect(res.status).toBe(200);
})
);
中间件
Startup 新增函数 expectMiddleware
,用于中间件的单元测试
注意,使用前需要先导入 @halsp/testing
import "@halsp/testing";
import "@halsp/http";
import { Middleware, Startup } from "@halsp/core";
class TestMiddleware extends Middleware {
fn() {
return 1;
}
invoke(): void | Promise<void> {
this.ok();
}
}
new Startup()
.useHttp()
.expectMiddleware(TestMiddleware, (md) => {
expect(md.fn()).toBe(1);
})
.add(TestMiddleware)
run();
WARNING
由于中间件执行顺序的原因,startup.expectMiddleware
需要写在 startup.add
之前
服务/依赖注入
Startup 新增函数 expectInject
,用于依赖注入服务的单元测试
安装了 @halsp/inject
的项目才能使用这个功能
npm install @halsp/inject
注意,使用前需要先导入 @halsp/testing
class TestService1 {
fn() {
return 1;
}
}
class TestService2 {
@Inject
private readonly testService1!: TestService1;
fn() {
return this.testService1.fn();
}
}
import "@halsp/testing";
import { Startup } from "@halsp/core";
new Startup()
.useInject();
.expectInject(TestService, (service) => {
expect(service.fn()).toBe(1);
});
import "@halsp/testing";
import { Startup } from "@halsp/core";
new Startup()
.useInject();
.inject(TestService, InjectType.Singleton)
.expectInject(TestService, (service) => {
expect(service.fn()).toBe(1);
});
runin
用于改变当前运行的路径,即改变 process.cwd()
的值
多用于与文件相关的单元测试
import { existsSync } from "fs";
import { runin } from "@halsp/testing";
await runin("./test", () => {
expect(existsSync("./file.txt")).toBeTruthy();
});