Quick Fix: Unit Testing "abstract_class"es

posted on Tuesday, September 22, 2009 at 9:09 AM PDT by Slippy Douglas | 1 comments

I’ve recently made the jump to using tests in Rails (2.3 as of this writing); coming from a background in game development, I’ve long stuck to the principle of “build it now, have QA test it later”. However, there comes a time in every programmer’s life when they feel the need to “code smarter, not harder”.

In the process of getting tests into one of my in-development apps, I came across one particular blunder. When trying to run rake test:units for the first time, I received this lovely output:

(in /Users/slippyd/Sites/orgclut2)
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -I"lib:test" "/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/unit/specific_thing_test.rb" "test/unit/helpers/nodes_helper_test.rb" "test/unit/invite_test.rb" "test/unit/mailer_test.rb" "test/unit/node_test.rb" "test/unit/cool_thing_test.rb" "test/unit/pile_test.rb" "test/unit/nifty_thing_test.rb" "test/unit/thing_test.rb" "test/unit/rad_thing_test.rb" "test/unit/better_thing_test.rb" "test/unit/awesome_thing_test.rb" "test/unit/user_test.rb" 
Loaded suite /Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
EEEEEEEEEEEEEEEEEEEEEEEE
Finished in 0.204718 seconds.

  1) Error:
test_the_truth(SpecificThingTest):
ActiveRecord::StatementInvalid: Mysql::Error: Table 'orgclut2_test.things' doesn't exist: DELETE FROM `things`

...

 24) Error:
test_should_unset_remember_token(UserTest):
ActiveRecord::StatementInvalid: Mysql::Error: Table 'orgclut2_test.things' doesn't exist: DELETE FROM `things`


24 tests, 0 assertions, 0 failures, 24 errors
rake aborted!
Command failed with status (1): [/System/Library/Frameworks/Ruby.framework/...]

Immediately, I knew the cause of the problem, my abstract parent class, “Thing”:

class Thing < ActiveRecord::Base
  self.abstract_class = true
  def self::class_from_type(type)
    if type.instance_of?(Class) && type.superclass == Thing
      type
    else
      type = type.to_s.classify
      type << 'Thing' unless type.match(/Thing$/)
      type = type.constantize
    end
  end

  # ...

end

After Googling for a bit and only finding some hints as to the solution (apparently, there aren’t as many people using abstract_class as there are using STI), I tried deleting my Thing fixture (test/fixtures/things.yml).

Voila! All is well again in Test-Land. I hope this helps any future Rubyists who come across this some problem.

Comments

Gert said on Monday, January 18, 2010:

You just did, thank you.

Post a comment


(required, but not displayed)

(optional, and awesome)

(required)