You need to enable JavaScript to run this app. Mocha+Chai如何验证函数返回对象是输入参数的克隆
优惠活动
大模型
产品
解决方案
定价
更多

Mocha+Chai如何验证函数返回对象是输入参数的克隆

问题排查与正确写法指引

第一步:先修复基础代码的低级错误

你写的clone.js首先存在导出逻辑错误:

// 你当前的代码
function makeClone (objectToClone) {
    return Object.assign({}, objectToClone)
}
module.exports = clone // 这里引用了不存在的变量clone,运行时直接报ReferenceError

修正为和定义的函数名匹配的导出逻辑:

function makeClone (objectToClone) {
    return Object.assign({}, objectToClone)
}
module.exports = makeClone

第二步:理清Chai expect断言的基本规则

你之前写的两处断言错误,本质是三个常见的新手误区:

  • 括号位置错误:expect(clone({a:1, b:2}).to.equal({a:1, b:2})) 把.to.equal写到了expect的括号内部,相当于把方法调用绑定在了clone()函数的返回值上,完全跳过了Chai的断言对象,根本不会触发校验。正确结构是把待断言值作为expect的入参,再在外层链式拼接断言方法:expect(clone({a:1, b:2})).to.equal({a:1, b:2})
  • 断言方法选择错误:哪怕括号位置写对,用.equal也永远通不过。因为Chai的.equal对应JS的严格相等判定(===),只校验两个值的内存引用是否完全一致——你用Object.assign生成的是全新对象,哪怕属性内容和原对象100%匹配,内存地址也不同,用equal判定必然失败。
  • 链式修饰词误用:你写的expect(clone({a: 1, b: 2})).to.be.equal.to({a: 1, b: 2}) 里,最后一个.to是无实际校验作用的语义修饰词,不是断言方法,写完之后等于没有执行任何值对比动作,测试相当于空跑。

新手记断言链逻辑不用死磕文档:expect(待校验值).[无逻辑作用的语义修饰词(to、be、been、is都可以随便加)].[真正的断言方法(期望值)],修饰词只用来让语句读着通顺,不改变校验逻辑。

第三步:验证浅克隆的完整测试用例

你要验证「函数返回的是对象的克隆」,其实需要两个维度的校验:

  • 克隆出来的对象,第一层属性值和原对象完全一致
  • 克隆出来的对象,和原对象不是同一个内存引用(避免函数偷懒直接返回原对象,根本没做克隆动作)

对应用到的Chai断言:

  • 校验属性值一致:用.eql,它会递归对比对象的所有可枚举属性值,不要求内存地址相同
  • 校验引用不同:用.equal搭配.not,专门用来对比内存引用是否一致

可直接运行的testClone.js代码

const expect = require('chai').expect
const makeClone = require('./clone.js')

describe('浅克隆函数', function () {
  it('返回对象的属性与传入对象完全匹配', function () {
    const sourceObj = {a: 1, b: 2}
    const clonedObj = makeClone(sourceObj)
    expect(clonedObj).to.eql(sourceObj)
  })

  it('返回的克隆对象与原对象不是同一内存引用', function () {
    const sourceObj = {a: 1, b: 2}
    const clonedObj = makeClone(sourceObj)
    expect(clonedObj).to.not.equal(sourceObj)
  })
})

内容的提问来源于stack exchange,提问作者Zepstack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 13:06:05