断言
为了帮助开发人员编写测试,Deno 标准库附带了一个内置的 断言模块,可以从 https://deno.land/std/assert/mod.ts
导入。
import { assert } from "https://deno.land/[email protected]/assert/mod.ts";
Deno.test("Hello Test", () => {
assert("Hello");
});
⚠️ 一些流行的断言库,如 Chai,也可以在 Deno 中使用,例如使用示例请参见 https://deno.land/std/testing/chai_example.ts。
断言模块提供了 14 个断言
assert(expr: unknown, msg = ""): asserts expr
assertEquals(actual: unknown, expected: unknown, msg?: string): void
assertExists(actual: unknown, msg?: string): void
assertNotEquals(actual: unknown, expected: unknown, msg?: string): void
assertStrictEquals(actual: unknown, expected: unknown, msg?: string): void
assertAlmostEquals(actual: number, expected: number, epsilon = 1e-7, msg?: string): void
assertInstanceOf(actual: unknown, expectedType: unknown, msg?: string): void
assertStringIncludes(actual: string, expected: string, msg?: string): void
assertArrayIncludes(actual: unknown[], expected: unknown[], msg?: string): void
assertMatch(actual: string, expected: RegExp, msg?: string): void
assertNotMatch(actual: string, expected: RegExp, msg?: string): void
assertObjectMatch( actual: Record<PropertyKey, unknown>, expected: Record<PropertyKey, unknown>): void
assertThrows(fn: () => void, ErrorClass?: Constructor, msgIncludes?: string | undefined, msg?: string | undefined): Error
assertRejects(fn: () => Promise<unknown>, ErrorClass?: Constructor, msgIncludes?: string | undefined, msg?: string | undefined): Promise<void>
除了上述断言之外,快照模块 还公开了 assertSnapshot
函数。此模块的文档可以在 此处 找到。
断言 跳转到标题
assert 方法是一个简单的“真值”断言,可用于断言任何可以推断为真的值。
Deno.test("Test Assert", () => {
assert(1);
assert("Hello");
assert(true);
});
存在 跳转到标题
assertExists
可用于检查值是否不是 null
或 undefined
。
assertExists("Denosaurus");
Deno.test("Test Assert Exists", () => {
assertExists("Denosaurus");
assertExists(false);
assertExists(0);
});
相等 跳转到标题
有三个相等断言可用,assertEquals()
、assertNotEquals()
和 assertStrictEquals()
。
assertEquals()
和 assertNotEquals()
方法提供了一般的相等性检查,能够断言基本类型和对象之间的相等性。
Deno.test("Test Assert Equals", () => {
assertEquals(1, 1);
assertEquals("Hello", "Hello");
assertEquals(true, true);
assertEquals(undefined, undefined);
assertEquals(null, null);
assertEquals(new Date(), new Date());
assertEquals(new RegExp("abc"), new RegExp("abc"));
class Foo {}
const foo1 = new Foo();
const foo2 = new Foo();
assertEquals(foo1, foo2);
});
Deno.test("Test Assert Not Equals", () => {
assertNotEquals(1, 2);
assertNotEquals("Hello", "World");
assertNotEquals(true, false);
assertNotEquals(undefined, "");
assertNotEquals(new Date(), Date.now());
assertNotEquals(new RegExp("abc"), new RegExp("def"));
});
相比之下,assertStrictEquals()
提供了一个更简单、更严格的基于 ===
运算符的相等性检查。因此,它不会断言两个相同对象的实例,因为它们在引用上不会相同。
Deno.test("Test Assert Strict Equals", () => {
assertStrictEquals(1, 1);
assertStrictEquals("Hello", "Hello");
assertStrictEquals(true, true);
assertStrictEquals(undefined, undefined);
});
assertStrictEquals()
断言最适合用于对两个基本类型进行精确检查。
数字的相等 跳转到标题
在测试数字之间的相等性时,务必牢记,其中一些数字无法通过 IEEE-754 双精度浮点表示法准确地描绘。
这在处理十进制数时尤其如此,在某些情况下 assertStrictEquals()
可能有效,但在其他情况下则无效
import {
assertStrictEquals,
assertThrows,
} from "https://deno.land/[email protected]/assert/mod.ts";
Deno.test("Test Assert Strict Equals with float numbers", () => {
assertStrictEquals(0.25 + 0.25, 0.25);
assertThrows(() => assertStrictEquals(0.1 + 0.2, 0.3));
//0.1 + 0.2 will be stored as 0.30000000000000004 instead of 0.3
});
相反,assertAlmostEquals()
提供了一种方法来测试给定的数字是否足够接近,以被认为相等。默认容差设置为 1e-7
,但可以通过传递第三个可选参数来更改它。
import {
assertAlmostEquals,
assertThrows,
} from "https://deno.land/[email protected]/assert/mod.ts";
Deno.test("Test Assert Almost Equals", () => {
assertAlmostEquals(0.1 + 0.2, 0.3);
assertAlmostEquals(0.1 + 0.2, 0.3, 1e-16);
assertThrows(() => assertAlmostEquals(0.1 + 0.2, 0.3, 1e-17));
});
实例类型 跳转到标题
要检查对象是否为特定构造函数的实例,可以使用 assertInstanceOf()
。这还有一个额外的好处,它可以让 TypeScript 知道传入的变量具有特定类型。
import { assertInstanceOf } from "https://deno.land/[email protected]/assert/mod.ts";
Deno.test("Test Assert Instance Type", () => {
const variable = new Date() as unknown;
assertInstanceOf(variable, Date);
// This won't cause type errors now that
// it's type has been asserted against.
variable.getDay();
});
包含 跳转到标题
有两种方法可用于断言值包含一个值,assertStringIncludes()
和 assertArrayIncludes()
。
assertStringIncludes()
断言对字符串进行简单的包含检查,以查看它是否包含预期的字符串。
Deno.test("Test Assert String Contains", () => {
assertStringIncludes("Hello World", "Hello");
});
assertArrayIncludes()
断言稍微高级一些,它可以在数组中找到一个值,以及在数组中找到一组值。
Deno.test("Test Assert Array Contains", () => {
assertArrayIncludes([1, 2, 3], [1]);
assertArrayIncludes([1, 2, 3], [1, 2]);
assertArrayIncludes(Array.from("Hello World"), Array.from("Hello"));
});
正则表达式 跳转到标题
您可以通过 assertMatch()
和 assertNotMatch()
断言来断言正则表达式。
Deno.test("Test Assert Match", () => {
assertMatch("abcdefghi", new RegExp("def"));
const basicUrl = new RegExp("^https?://[a-z.]+.com$");
assertMatch("https://www.google.com", basicUrl);
assertMatch("http://facebook.com", basicUrl);
});
Deno.test("Test Assert Not Match", () => {
assertNotMatch("abcdefghi", new RegExp("jkl"));
const basicUrl = new RegExp("^https?://[a-z.]+.com$");
assertNotMatch("https://deno.land/", basicUrl);
});
对象 跳转到标题
使用 assertObjectMatch
检查 JavaScript 对象是否与对象的属性子集匹配。
// Simple subset
assertObjectMatch(
{ foo: true, bar: false },
{
foo: true,
},
);
抛出 跳转到标题
在 Deno 中,有两种方法可以断言某件事是否抛出错误,assertThrows()
和 assertRejects()
。这两个断言都允许您检查是否抛出了 错误,抛出的错误类型以及错误消息是什么。
这两个断言之间的区别在于 assertThrows()
接受一个标准函数,而 assertRejects()
接受一个返回 Promise 的函数。
assertThrows()
断言将检查是否抛出了错误,并且可以选择检查抛出的错误是否为正确的类型,并断言错误消息与预期一致。
Deno.test("Test Assert Throws", () => {
assertThrows(
() => {
throw new Error("Panic!");
},
Error,
"Panic!",
);
});
assertRejects()
断言稍微复杂一些,主要是因为它处理 Promise。但基本上它会捕获 Promise 中抛出的错误或拒绝。您还可以选择检查错误类型和错误消息。这可以类似于 assertThrows()
一起使用,但使用异步函数。
Deno.test("Test Assert Throws Async", async () => {
await assertRejects(
() => {
return new Promise(() => {
throw new Error("Panic! Threw Error");
});
},
Error,
"Panic! Threw Error",
);
await assertRejects(
() => {
return Promise.reject(new Error("Panic! Reject Error"));
},
Error,
"Panic! Reject Error",
);
});
自定义消息 跳转到标题
Deno 的每个内置断言都允许您覆盖标准的 CLI 错误消息(如果您愿意)。例如,此示例将输出“值不匹配!”而不是标准的 CLI 错误消息。
Deno.test("Test Assert Equal Fail Custom Message", () => {
assertEquals(1, 2, "Values Don't Match!");
});
自定义测试 跳转到标题
虽然 Deno 带有强大的 断言模块,但总有一些特定于项目的内容可以添加。创建 自定义断言函数
可以提高可读性并减少代码量。
import { AssertionError } from "https://deno.land/[email protected]/assert/mod.ts";
function assertPowerOf(actual: number, expected: number, msg?: string): void {
let received = actual;
while (received % expected === 0) received = received / expected;
if (received !== 1) {
if (!msg) {
msg = `actual: "${actual}" expected to be a power of : "${expected}"`;
}
throw new AssertionError(msg);
}
}
在您的代码中像这样使用此匹配器
Deno.test("Test Assert PowerOf", () => {
assertPowerOf(8, 2);
assertPowerOf(11, 4);
});