Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby/Rspec: Possible to compare the content of two objects?

Tags:

ruby

rspec

I've created 2 different objects in ruby with exactly the same attributes and values.

I'd like to compare now that the content of both objects is the same but the following comparisons:

actual.should == expected
actual.should eq(expected)
actual.should (be expected)

fail with:

  Diff:
  @@ -1,4 +1,4 @@
  -#<Station:0x2807628
  +#<Station:0x2807610

Is there any way in rspec/ruby to easily achieve this?

Cheers!!

like image 785
mickael Avatar asked Dec 16 '12 05:12

mickael


People also ask

How do you compare two values of objects?

In Java, the == operator compares that two references are identical or not. Whereas the equals() method compares two objects. Objects are equal when they have the same state (usually comparing variables). Objects are identical when they share the class identity.

What is describe in RSpec?

The word describe is an RSpec keyword. It is used to define an “Example Group”. You can think of an “Example Group” as a collection of tests. The describe keyword can take a class name and/or string argument.

What is RSpec in Ruby?

RSpec is a testing tool for Ruby, created for behavior-driven development (BDD). It is the most frequently used testing library for Ruby in production applications. Even though it has a very rich and powerful DSL (domain-specific language), at its core it is a simple tool which you can start using rather quickly.


3 Answers

An idiomatic way to do this is to override the #== operator:

class Station
  def ==(o)
    primary_key == o.primary_key
  end

  def hash
    primary_key.hash
  end
end

When you do this, you generally want to override the #hash method as well. It is less common to override #eql? or #equal?.

EDIT: Another thing you can do in this specific case, which does not involve overriding #==, is to make a custom RSpec matcher.

like image 144
Eric Walker Avatar answered Nov 04 '22 06:11

Eric Walker


Use the have_attributes matcher to specify that an object's attributes match the expected attributes:

  Person = Struct.new(:name, :age)
  person = Person.new("Jim", 32)

  expect(person).to have_attributes(:name => "Jim", :age => 32)
  expect(person).to have_attributes(:name => a_string_starting_with("J"), :age => (a_value > 30) )

Relishapp RSpec Docs

like image 40
JE42 Avatar answered Nov 04 '22 05:11

JE42


A bit late, but you could serialize it, per example:

require 'json'

expect(actual.to_json).to eq(expected.to_json) #new rspec syntax
actual.to_json.should eq(expected.to_json) #old rspec syntax
like image 26
Kybi Avatar answered Nov 04 '22 06:11

Kybi