You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rspec测试同输入值对象实例==相等性校验失败解决方法

Rspec值对象相等性判断失败解决

问题现象

编写Rspec用例验证PixKey实例相等性时,相同入参独立创建的两个实例无法通过eq匹配,报错核心差异为两个实例内存地址不同,所有实例属性完全一致:

  • 测试代码:
describe '#==' do
  let(:cpf) {described_class.new('01201201202')}

  it 'verifies the key equality' do
    expect(cpf).to eq described_class.new('01201201202')
  end
end
  • 报错关键信息:
expected: #<PixKey:0x0000018d191b8670 @value="01201201202", @key="01201201202", @type="cpf">
     got: #<PixKey:0x0000018d191b8b70 @value="01201201202", @key="01201201202", @type="cpf">
(compared using ==)

根因说明

Ruby中BasicObject提供的默认==方法,仅判断两个对象是否为内存中同一个实例,不会自动对比实例的属性值。因此相同入参new出来的两个独立实例,默认会被判定为不相等,不符合值对象的相等性预期。

实现方案

方案1:手动重写类的相等判断方法

在PixKey类中重写==方法,基于值对象的核心属性做相等判断,同时配套重写eql?和hash方法,保证数组去重、Hash键匹配等场景下逻辑一致:

class PixKey
  # 类原有业务逻辑
  attr_reader :value, :key, :type

  def initialize(input_value)
    # 原有初始化逻辑,给@value、@key、@type赋值
  end

  def ==(other)
    # 先校验比较对象类型,避免跨类误判
    return false unless other.is_a?(self.class)
    # 所有核心属性值一致则判定相等
    value == other.value && key == other.key && type == other.type
  end

  def eql?(other)
    self == other
  end

  def hash
    [value, key, type].hash
  end
end

方案2:使用Struct构建值对象

如果PixKey是无额外复杂状态的纯值对象,可以直接用Ruby标准库的Struct定义类,Struct会自动生成基于属性值判断的相等逻辑,无需手动编写:

PixKey = Struct.new(:value, :key, :type, keyword_init: true) do
  # 在这里写类的其他业务方法,比如CPF格式校验逻辑
end

验证结果

实现上述任意一种方案后,原有Rspec用例即可正常通过,相同入参创建的实例会被正确判定为相等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:03:20