Chai 中文文档 下载 App

.above .below .least .most .within .closeTo 数值比较全览

六个比较断言

写法语义参数
.above(n)大于 n(>n)数值或日期
.below(n)小于 n(<n)数值或日期
.least(n)大于等于 n(≥n)数值或日期
.most(n)小于等于 n(≤n)数值或日期
.within(min, max)区间包含([min, max])数值或日期
.closeTo(expected, delta)近似相等 \actual - expected\≤ delta数值

大于 / 小于:above / below

expect(42).to.be.above(40);          // ✅ 42 > 40
expect(42).to.be.above(42);          // ❌ 42 不大于 42
expect(42).to.be.below(50);          // ✅ 42 < 50
expect(42).to.be.below(42);          // ❌ 42 不小于 42

大于等于 / 小于等于:least / most

expect(42).to.be.at.least(42);       // ✅ 42 ≥ 42
expect(42).to.be.at.least(40);       // ✅ 42 ≥ 40
expect(42).to.be.at.most(42);        // ✅ 42 ≤ 42
expect(42).to.be.at.most(50);        // ✅ 42 ≤ 50

注意 .least 前面习惯加 .at:expect(x).to.be.at.least(n)。.at 是一个语言链,只是让句子通顺。不加也可以:expect(x).to.be.least(n)。

区间包含:within

expect(42).to.be.within(40, 50);     // ✅ 42 ∈ [40, 50]
expect(42).to.be.within(42, 42);     // ✅ 边界值也通过
expect(42).to.be.within(50, 40);     // ⚠️ min > max 时 Chai 会交换它们,仍然通过

.within 的区间是闭区间——两个边界值都包含在内。

近似相等:closeTo

解决浮点精度问题的利器:

// 经典浮点问题
expect(0.1 + 0.2).to.equal(0.3);
// AssertionError: expected 0.30000000000000004 to equal 0.3

// 用 closeTo 指定允许误差
expect(0.1 + 0.2).to.be.closeTo(0.3, 0.0001);  // ✅

delta 参数表示允许的绝对误差:|actual - expected| ≤ delta。

expect(3.14159).to.be.closeTo(3.14, 0.01);    // ✅ |3.14159 - 3.14| = 0.00159 ≤ 0.01
expect(3.14159).to.be.closeTo(3.14, 0.001);   // ❌ 0.00159 > 0.001

日期也能比较

.above / .below / .least / .most / .within 都支持 Date 对象:

const today = new Date();
const tomorrow = new Date(today.getTime() + 86400000);

expect(tomorrow).to.be.above(today);
expect(today).to.be.at.most(tomorrow);
expect(new Date('2024-01-01')).to.be.within(
  new Date('2023-12-31'),
  new Date('2024-01-02')
);

Chai 内部调用 .getTime() 比较时间戳,所以也可以直接比较时间戳数值:

expect(tomorrow.getTime()).to.be.above(today.getTime());

assert 风格对应

assert.isAbove(42, 40);
assert.isBelow(42, 50);
assert.isAtLeast(42, 42);
assert.isAtMost(42, 42);
assert.isWithin(42, 40, 50);
assert.isCloseTo(0.1 + 0.2, 0.3, 0.0001);

assert 风格的 .isWithin 参数顺序不同:assert.isWithin(value, min, max)——第一个是实际值,后面是区间。而 expect 风格是 expect(value).to.be.within(min, max)——实际值在 expect 里。

常见陷阱

.within 边界交换

如果你写了 expect(x).to.be.within(50, 40)(min > max),Chai 会自动交换成 (40, 50),不会报错。这在边界是变量时可能掩盖 bug——最好保证 min ≤ max。

浮点精度没处理

测试中涉及乘除运算时,随时可能遇到精度问题。养成习惯:涉及小数运算的比较,先用 .closeTo 而不是 .equal。

日期比较的时区问题

比较日期时确保两端使用同一时区的 Date 对象。如果一端用 UTC 一端用本地时区,可能出现意外结果。

下一步