Mocking ActiveRecord Associations 4
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
Rails Unit Test Confusion 1
I think I understand why the unit tests in Rails were confusing me. I had assuming that unit test fixtures ran YAML into some kind of in-memory activerecord object. But in reality, fixtures will put data into a test database and then unit tests will interact with it.
As far as I understand it:
1) An integration test is one where the test code goes outside the realm of the class and has a dependency on an external entity.
2) Databases are external entities.
3) Fixtures will write to the test database.
Therefore:
Any test containing a fixture is an integration test, even if it’s in test/unit and extends Test::Unit::TestCase.
Furthermore:
Unit tests are tests that can be run in isolation, in any order, without any external dependencies.
Whew. Had to get that out of my system.
Not that I don’t understand the rationale; or that using fixtures could be extremely handy. But a spade is a spade.
As usual, as soon as I realized the underlying issue, there was no shortage of help, Jay Fields being the most helpful.
Starting from Scratch
A little over a week ago, I made the appropriate sacrifices, made a backup to an external machine, setup a new computer (after figuring out why it wouldn’t POST with a USB keyboard plugged into it) and then transferred the hard drives of my old computer into the new one.
Long story short, the hard drive with all my important data died, and the backup contains some hairball that causes the backup server to freeze when the data is transferred. Oh, and my laptop died as well. The same day.
Ever get the feeling the ground has just crumbled under your feet?
I lost some stuff. Most annoyingly, I lost all my software registration keys. This is good in a way – it means I can try mint.com without having to worry about my old data. And I’ve found that I tend to use online services such as Google Docs and Google Bookmarks over any local solution, so in some cases there is no need to backup at all.
I spent most of the beginning of the week reinstalling my toolkit: Perl, Java, Ruby, RSIGuard, jEdit, etc. And making sure this can never happen again. I have everything local (and this server) backed up onto Amazon S3, using s3sync. I also have a weekly backup of the database onto S3, and I’ve already restored it to check it’s still good.
Of course, it’s going to take me three full days to upload my MP3s onto S3, but I think it’s going to be worth it. And eventually, iTunes will get smart enough that I’ll never need to download them again.