| ||||
A blog about Ruby, Rails and other Tech. Mostly.Back to blog
Gotcha 1 Failing tests. We'd like them to pass of course. But there is something strange going on - the error is not a test error, it seems to come from rails itself:
1) Error:
test_searcher_email(OrderMailerTest):
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.4/lib/active_record/fixtures.rb:498:in `orders'
./test/unit/order_mailer_test.rb:22:in `test_searcher_email'
1 tests, 0 assertions, 0 failures, 1 errors
What does it mean? The clue here is that the error comes from fixtures.rb. The other thing to note is that I have a setup in my test:
def setup
ActionMailer::Base.delivery_method = :test
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.deliveries = []
...
end
Which should be fine, but there is this nasty error. Let's try something in the setup method - we'll add a call to super there:
def setup
ActionMailer::Base.delivery_method = :test
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.deliveries = []
...
super
end
And the result:
Started . Finished in 0.160284 seconds. 1 tests, 1 assertions, 0 failures, 0 errorsGreat, that's fixed it. But why? Well it took me a while to find it. Have a look in /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.4/lib/active_record/fixtures.rb - there is your culprit at line 554:
alias_method :setup, :setup_with_fixtures
So the rule is, if you override setup you need to call super otherwise you don't get your fixtures set up properly.
Gotcha 2 Ever tried to test your routes? You should. But if you have routes that depend on what's in your database you've got a problem. Why? Because the routing is initialised before any fixtures are loaded. In fact none of the test related code is loaded at that point. So your tests just won't work. I don't know a good way to fix this. In the end I opted for a fudge at the beginning of routes.rb:
if ENV['RAILS_ENV'] == "test" && Category.count == 0
Category.create!(:name=>"Families and Friends", :alternative_name=>"Family")
end
And I have a fixture that contains the same information. This isn't really DRY, but I don't really see a good way to do this. Maybe we could read the fixtures file ourselves and get the data from there.
But at least the tests run ok now. Back to blog |