A blog about Ruby, Rails and other Tech. Mostly.Back to blog
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 =  ... endWhich 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 endAnd 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_fixturesSo the rule is, if you override setup you need to call super otherwise you don't get your fixtures set up properly.
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") endAnd 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