fearless_fool
fearless_fool

Reputation: 35159

how to test collections of ActiveRecords in rspec?

I like RSpec, and I really like its =~ array operator matcher to verify that an array contains a specific set of elements, regardless of ordering.

But not surprisingly, it tests pointer equality, not content equality, so the following won't work:

class Flea < ActiveRecord::Base ; end
class Dog < ActiveRecord::Base
  has_many :fleas
end

@d = Dog.create
@d.fleas << (@f1 = Flea.create)
@d.fleas << (@f2 = Flea.create)

@d.fleas.should =~ [@f1, @f2]

So I find myself frequently writing this in my RSpec tests:

@d.fleas.map {|f| f.id}.should =~ [@f1.id, @f2.id]

... which reeks of bad code smell. Does RSpec provide a better way to verify a collection of ActiveRecord objects, regardless of the order returned? Or at least is there a prettier way to code such a test?

Upvotes: 3

Views: 4373

Answers (1)

RyanWilcox
RyanWilcox

Reputation: 13974

ActiveRecord::Relations don't work like Arrays (as you found out). See Issue #398 on the GitHub RSpec-Rails Issue board.

The answer is to add this line of code to your spec_helper.rb:

RSpec::Matchers::OperatorMatcher.register(ActiveRecord::Relation, '=~', RSpec::Matchers::MatchArray)

Upvotes: 4

Related Questions