On this page
Standard Assertions (@std/assert)
Overview Jump to heading
A library of assertion functions.
If the assertion is false an AssertionError will be thrown which will
result in pretty-printed diff of the failing assertion.
This module is browser compatible, but do not rely on good formatting of values for AssertionError messages in browsers.
import { assert } from "@std/assert";
assert("I am truthy"); // Doesn't throw
assert(false); // Throws `AssertionError`
Add to your project Jump to heading
deno add jsr:@std/assert
See all symbols in @std/assert on
什么是断言? Jump to heading
断言是一种必须为真的检查。如果不为真,程序将抛出一个带有有用信息和差异的 AssertionError,帮助你快速发现出错原因。
在测试中,断言用于验证行为。在应用代码中,它们可以用来记录和保护不变量(前置条件/后置条件)。在 TypeScript 中,一些断言(如 assert(condition))还能在检查后缩小类型范围。
何时使用 @std/assert? Jump to heading
该包中的工具使测试失败变得清晰且可操作(支持漂亮的差异显示和聚焦的消息)。通过内联编码期望,提高测试代码的可读性。
断言帮助快速失败,防止假设被违反而产生的隐性 bug。
在测试中应广泛使用断言来验证行为,捕获回归。
示例 Jump to heading
import {
assert,
assertAlmostEquals,
assertArrayIncludes,
assertEquals,
assertExists,
assertFalse,
assertMatch,
assertNotEquals,
assertObjectMatch,
assertRejects,
assertStrictEquals,
assertThrows,
} from "@std/assert";
// 基本的真值断言和类型缩小
const value: unknown = "hello";
assert(typeof value === "string", "Expected a string");
// value 现在被缩小为 string 类型
// 深度结构相等(对象/数组)
assertEquals({ a: 1, b: [1, 2] }, { a: 1, b: [1, 2] });
assertNotEquals([1, 2], [1, 2, 3]);
// 严格(引用/标识)相等,适用于基本类型和引用类型
assertStrictEquals(1, 1);
assertFalse(false);
assertExists("non-empty"); // 不是 null 或 undefined
// 模式匹配 & 数值比较
assertMatch("deno.land", /deno/);
assertAlmostEquals(0.1 + 0.2, 0.3, 1e-15);
// 集合
assertArrayIncludes([1, 2, 3], [2, 3]);
assertObjectMatch(
{ id: 42, name: "A", meta: { ok: true } },
{ name: "A", meta: { ok: true } }, // 子集必须匹配
);
// 错误断言:同步 vs 异步
assertThrows(() => JSON.parse("not json"), SyntaxError);
await assertRejects(() => fetch("https://deno.land/404"));
如何选择合适的相等检查 Jump to heading
断言相等主要有两种类型:
assertEquals Jump to heading
递归地按结构和内容比较值。对于数组,顺序必须一致;对于普通对象,键的顺序无关紧要。最适合比较序列化样式的数据(对象、数组、数字、字符串、布尔值)。
assertStrictEquals Jump to heading
检查两个操作数是否严格相同(基本类型)或引用相同(对象),语义类似于 Object.is。
例如:
assertStrictEquals({ x: 1 }, { x: 1 }) 会失败(引用不同)
assertEquals({ x: 1 }, { x: 1 }) 通过
assertStrictEquals(NaN, NaN) 通过(类似 Object.is)
示例 Jump to heading
// 深度相等 vs 严格相等
assertEquals({ a: 1 }, { a: 1 }); // ✅ 结构/内容相同
// assertStrictEquals({ a: 1 }, { a: 1 }); // ❌ 引用不同
const obj = { a: 1 };
assertStrictEquals(obj, obj); // ✅ 引用相同
// 数组:顺序在相等中很重要
assertEquals([1, 2, 3], [1, 2, 3]); // ✅
// assertEquals([1, 2, 3], [3, 2, 1]); // ❌ 顺序不同
// 数字:浮点数比较
// 非精确数学运算建议使用 assertAlmostEquals
// assertEquals(0.1 + 0.2, 0.3); // ❌
assertAlmostEquals(0.1 + 0.2, 0.3, 1e-15); // ✅
- 使用
assertEquals来比较数据的形状和值;当需要关心引用身份或基本类型的严格相等时,用assertStrictEquals。 - 对部分对象检查,优先使用
assertObjectMatch而非断言整个对象。 - 比较大且嵌套复杂的结构时,
assertEquals详尽但效率较低——性能关键的热测试中,建议使用严格或有针对性的检查。
编写良好的失败提示信息 Jump to heading
所有断言函数的最后一个参数都可以传入可选的消息。编写这些消息帮助开发者理解失败发生的位置及修正方式。保持消息简洁且以用户为中心:
assert(Array.isArray(items), "items 必须是数组");
assertEquals(result.status, 200, "API 应返回 200 OK");
测试使用示例 Jump to heading
配合 Deno.test 使用:
Deno.test("adds numbers", () => {
assertEquals(1 + 2, 3);
});
Deno.test("throws on invalid JSON", () => {
assertThrows(() => JSON.parse("nope"), SyntaxError);
});
Deno.test("rejects for failed fetch", async () => {
await assertRejects(() => fetch("https://deno.land/404"));
});
小贴士 Jump to heading
- 处理浮点数运算时,使用带容差的
assertAlmostEquals。 - 对于部分对象的检查,使用
assertObjectMatch而非整形断言。 assert(condition)在 TS 中带有断言签名 (asserts condition),可以缩小类型范围。- 针对 Promise 推荐用
assertRejects,针对同步代码用assertThrows,不要混用。
参见 Jump to heading
@std/expect提供 Jest 风格的 BDD 断言 API,如果你喜欢链式匹配器,可以考虑使用。