JavaScript 断言函数的奇妙冒险:手搓一个极简版 Jest 的 expect

135 阅读2分钟

JavaScript 断言函数的奇妙冒险:手搓一个极简版 Jest 的 expect

一、需求分析:当法官的代码人生

最近在刷 LeetCode 时遇到了一个有趣的题目(),要求我们实现一个 expect 函数。这让我想起了测试框架中的断言功能——就像代码世界的法官,时刻准备敲下正义的小锤子:

function expect(val) {
    return {
        toBe: (target) => {
            if (val === target) return true
            throw new Error("Not Equal")
        },
        notToBe: (target) => {
            if (val !== target) return true
            throw new Error("Equal")
        }
    }
}

二、技术解剖:闭包的三重奏

1. 函数式编程的妙用

这个实现完美展现了 JavaScript 的函数式特性。expect 作为高阶函数,返回的对象方法共享着闭包中的 val——就像三个密谋的侦探共享关键线索。

2. 错误处理的艺术

当值不符合预期时,我们抛出错误而不是返回 false。这种设计参考了测试框架的常见做法,就像法官发现违法行为时不会悄悄记在本子上,而是直接敲锤宣判。

3. 类型安全的博弈

使用 ===!== 运算符确保了类型安全。试想如果用 ==expect(0).toBe('') 就会成为漏网之鱼,就像用错法条的糊涂法官。

三、实战演练:当代码成为法庭

// 原告:数字5
const plaintiff = expect(5)

try {
    // 被告A:数字5(当庭释放)
    console.log(plaintiff.toBe(5)) // ✅
    
    // 被告B:字符串'5'(当庭逮捕)
    plaintiff.toBe('5') // 🚨 Error: Not Equal
} catch (e) {
    console.error(e.message)
}

四、扩展思考:从玩具到工具

虽然这个实现很精妙,但与专业测试框架相比就像玩具水枪 VS 消防车。真正的 Jest 等框架还有这些超能力:

  1. 异步断言:能处理 Promise
  2. 自定义匹配器.toBeInstanceOf().toContain()
  3. 错误追踪:精确到行号的堆栈信息

五、人生哲理:代码如人生

这个题目教会我们:

  • 精确判断(===)比模糊认可(==)更重要
  • 及时报错比沉默失败更有价值
  • 函数闭包就像人际关系,共享的记忆造就独特的化学反应

下次当你的代码需要判断是非时,不妨试试这个手搓的「正义小锤子」吧!👨⚖️👩⚖️