测试 RSpec 如何对比两个内容相同的对象?

beyondyuqifeng · 2014年05月09日 · 最后由 beyondyuqifeng 回复于 2014年05月10日 · 2801 次阅读

如题,这个该怎么对比呢,使用“==”等测试无法通过,详细可以看这个提问: http://stackoverflow.com/questions/13898826/ruby-rspec-possible-to-compare-the-content-of-two-objects

环境是在 rails 中 补充代码如下: 自己定义的类:

class HighChart
  attr_accessor :chart, :title, :subtitle, ...

  .
  .
  .
end

需要测试的方法:

module HighchartsHelper do
  def get_highchart_object
    .
    .
    .
    highchart_object = HighChart.new(...)
  end
end

Rspec 代码:

describe HighchartsHelper do
  describe "#get_highchart_object" do
    it "return highchart object" do
      highchart_object = HighChart.new(...)
      expect(helper.get_highchart_object).to eq(highchart_object)
    end
  end
end

HighChart.new() 创建的对象的内容(chart, title, subtitle 等)都是一样的

请贴问题代码。

#1 楼 @billy 你好,附的链接中有说明哈,具体可以看一下这个 stackoverflow 的问题,我和他的问题一样,只是这个问题还没有人解答好

#2 楼 @beyondyuqifeng 你给的链接已经有答案了,== 方法是可定义的,取决于你要对比什么对象,如果是 ActiveRecord 就已经内部处理好了,所以才要你贴代码看你到底要做什么。

@beyondyuqifeng 他的那个问题提得就有问题,三个 expect 连在一起,肯定错的是第一个,后面的连执行机会都没有。

我不知道你具体比较什么,所以不好具体回答。

==好像是已经 deprecate。一般测值相等是用eq。你如果比较两个 object 值是否相等就应该用eq。测恒等是用be, 会比较 object id,一般情况很少用。

@billy @Rei 已经补充了代码,麻烦再帮我看看,代码做了简化,但是就是这么个意思,同样用“==”和 eq 都是无法通过

Equality and Identity

eq(expected) # same value
eql(expected) # same value and type
equal(expected) # same object

#6 楼 @ericguo 链接赞一个,但是我确实用了 eq 唉,但是不通过的结果就是 object id 不同导致挂掉了,对象的 value 都是一样的

@beyondyuqifeng 你比较的两个是不同的 object,又不是值,肯定是不能等价的。

另外,你这个测试没有什么意义,证明不了什么东西。

你可以,第一,测返回的是不是 Highchart 的 instance, 第二,返回的 instance 是不是有期望的值。

let(:chart){helper.get_highchart}

describe "foo bar" do
  expect(chart).to be_kind_of(Highchart)
  expect(chart.some_attribute).to eq(expected_value)
end

#8 楼 @billy 第二种,这个之前也有考虑去 check 返回的 instance 是不是有期望的值,但是如果这个 instance 有 10 多个 attribute,那岂不是要写十多个

expect(chart.some_attribute).to eq(expected_value)

所以想找一个可以比较两个不同的 object,但是其 value 是一样的方法,这样就只用一个 eq 就可以搞定,可能我问题也没有描述明白,见谅啊

@beyondyuqifeng 你多虑了。测试又不是克隆,只要测到关键点就可以了。

#9 楼 @beyondyuqifeng 我觉得这个问题上,应该重新去定义 Hignchart 被 eql 调用的哪个方法。这样就可以使用 eql 进行两个不同 object id 的对象 value 比对了。 rails 默认当然无法判断两个 object id 不同的对象的相等性

看这里:https://www.relishapp.com/rspec/rspec-expectations/v/2-0/docs/matchers/equality-matchers

在你的情况下,我的建议是

  1. 使用 expect(obj1).to eql(obj2)
  2. 重定义 Highchart 的 eql? 方法。在其中指定好你想要进行比较的各个 property 是如何进行比较。

如果是 ActiveRecord 的 instance,一定要比较全部 attributes 的话,你可以用

attr1 = obj1.attributes
attr1.delete('id')
attr2 = obj2.attributes
attr2.delete('id')
expect(attr1).to eq(attr2)

不过很少必要。

@billy @alsotang 恩,了解了,我再去折腾折腾,thx

#14 楼 @beyondyuqifeng 有结果的话说一声

😄,看一下 lazy_high_chart 的测试代码

@xds2000 哈哈,好的,这个 lazy_high_chart 感觉用起来很复杂唉,后来就参照你的写了一个自己订制的使用简单的,在此谢过哇

需要 登录 后方可回复, 如果你还没有账号请 注册新账号