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
相关产品推荐
相关产品推荐

