Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 568
fearless_fool Avatar asked Nov 22 '25 14:11

fearless_fool


1 Answers

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)
like image 82
RyanWilcox Avatar answered Nov 25 '25 04:11

RyanWilcox