November 09, 2007 23:29
Flexmock does mocking of ActiveRecord objects if you ask it nicely, but it doesn't say much about associations.

It turns out that ActiveRecord does the same thing that Hibernate does and uses an internal proxy. So if you want a post containing a single image as an association, do this:

# Create a single image.
image = flexmock(:model, Image) { |mock|
  mock.should_receive(:url).and_return('/post/10/blah.jpg')
  mock.should_receive(:name).and_return('Blah Description')      
}

# It's an association proxy pretending to be an array.
images = flexmock(ActiveRecord::Associations::HasManyAssociation) { |mock|
  mock.should_receive(:find_by_name).and_return(image)
}

# The post itself.
post = flexmock(:model, Post) { |mock|
  mock.should_receive(:object_id).and_return('10')
  mock.should_receive(:images).and_return(images)
}

This is a Law of Demeter violation, so the better solution may be to have a get_images method.

More info here:

Misunderstanding the Law of Demeter
Demeter's Revenger
Loose Coupling takes Tight Logic

« Toodledo | Home | Rails Unit Test Confusion »

Why mock? Use fixtures! Make sure to use the foxy fixtures though. http://m.onkey.org/2007/10/26/fixtures-go-foxy

I've got nothing against fixtures, but I was having issues with db:migrate and the test database. Eventually resolved it as HP's printer driver adding a VERSION environment variable, which confused rake.

name
url