Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Fixtures names can't start with 'test'

#261

After moving from Rails 1.2 to 2.0.2 using fixtures whose name starts with 'test' fails. Running 'rake' when having fixture test_whatevers.yml results in an

1) Error:

test_whatevers(ActionController::TestCase):

ArgumentError: wrong number of arguments (0 for 1)

/var/lib/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/test_case.rb:48:in `initialize'

/var/lib/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/test_case.rb:48:in `new'

/var/lib/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/test_case.rb:48:in `setup_without_fixtures'

/var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/fixtures.rb:979:in `full_setup'

/var/lib/gems/1.8/gems/activesupport-2.0.2/lib/active_support/testing/default.rb:7:in `run'

To reproduce

  • Create new project: 'rails foo'
  • In foo, create a model TestWhatever: 'script/generate model TestWhatever'
  • Migrate: 'rake db:migrate'
  • Run tests: 'rake'
  • See expection above.

All is fine when the model is named 'TesxWhatever' or 'WhateverTest'.

Reported by Menno · May 27th, 2008 @ 03:15 PM

State: wontfix
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Menno
    Menno
    • Title changed from ArgumentError using fixtures named test... to ArgumentError using fixtures named test*

    May 27th, 2008 @ 03:18 PM

  2. Menno
    Menno

    It turns out things are messed up by line 54 of Ruby 1.8.6's test/unit/testcase.rb:

    tests = method_names.delete_if {|method_name| method_name !~ /^test./}
    

    This is in the self.suite method which "Rolls up all of the test* methods in the fixture into one suite, creating a new instance of the fixture for each method."

    When you remove your fixture names from method_names, i.e. add a line tests.delete("test_whatevers") after line 54, all is fine again. But obviously this is no solution.

    May 30th, 2008 @ 04:12 PM

  3. Menno
    Menno
    • Title changed from ArgumentError using fixtures named test* to Fixtures names can't start with 'test'

    May 30th, 2008 @ 05:54 PM

  4. oddlyzen
    oddlyzen

    wouldn't it be better (instead of checking the method_name string) to check the module/class hierarchy for the testing module..? checking the string/name assumes that everyone is going to follow the conventions. we know that's not true, likely, or maybe even possible.

    May 30th, 2008 @ 06:43 PM

  5. josh
    josh
    • State changed from new to wontfix
    • Tag set to 2.0-stable, actionpack, activerecord, bug

    July 17th, 2008 @ 02:08 AM

  6. Menno
    Menno

    Thanks for the update. Should I interpret the tags as "fixed in 2.1"?

    July 17th, 2008 @ 09:36 AM

  7. Menno
    Menno
    • Tag changed from 2.0-stable, actionpack, activerecord, bug to 2.0-stable, actionpack, activerecord, bug

    Issue still present in Rails 2.1.1

    September 18th, 2008 @ 10:45 AM

  8. Rob Lucas
    Rob Lucas

    I'm getting this bug as a result of having a model called "Testimonial". It seems that I can't have fixtures at all for this model because of this bug. Surely we can handle these things more intelligently than this!

    October 2nd, 2008 @ 12:00 PM

  9. Rob Lucas
    Rob Lucas

    Rails apparently regards "Test" as a reserved name for controllers, probably for this kind of reason. When trying to generate a controller just called "Test", I get the following response in Rails 2.1.1:


    The name 'Test' is either already used in your application or reserved by Ruby on Rails.

    Please choose an alternative and run this generator again.

    Suggestions:

    trial trial run tryout mental test mental testing psychometric test examination exam run prove try try out examine essay screen

    quiz

    But models with names such as "testimonial", "testament" etc should certainly still be possible, and I can't really see why something like "test_driver" shouldn't work either. I've managed to get around this problem by hacking the line of test/unit/testcase.rb that is mentioned by Menno above. Rather than going in and hacking the actual original file, I'm overriding it by requiring a file in my troubled unit tests like:

    
    module Test
      module Unit
        class TestCase
            # Require this file in any unit tests for models starting with the letters "test".
            # Overrides the suite method in Ruby's test/unit/testcase.rb so that we don't end
            # up trying to run a spurious unit test method of the same name as our model
            def self.suite
              method_names = public_instance_methods(true)
              tests = method_names.delete_if {|method_name| method_name !~ /^test./ || method_name == "test_whatevers"}
              suite = TestSuite.new(name)
              tests.sort.each do
                |test|
                catch(:invalid_test) do
                  suite << new(test)
                end
              end
              if (suite.empty?)
                catch(:invalid_test) do
                  suite << new("default_test")
                end
              end
              return suite
            end
        end
      end
    end
    

    October 2nd, 2008 @ 05:07 PM

  10. Rob Lucas
    Rob Lucas

    Rails apparently regards "Test" as a reserved name for controllers, probably for this kind of reason. When trying to generate a controller just called "Test", I get the following response in Rails 2.1.1:


    The name 'Test' is either already used in your application or reserved by Ruby on Rails.

    Please choose an alternative and run this generator again.

    Suggestions:

    trial trial run tryout mental test mental testing psychometric test examination exam run prove try try out examine essay screen quiz


    But models with names such as "testimonial", "testament" etc should certainly still be possible, and I can't really see why something like "test_driver" shouldn't work either. I've managed to get around this problem by hacking the line of test/unit/testcase.rb that is mentioned by Menno above. Rather than going in and hacking the actual original file, I'm overriding it by requiring a file in my troubled unit tests like:

    
    module Test
      module Unit
        class TestCase
            # Require this file in any unit tests for models starting with the letters "test".
            # Overrides the suite method in Ruby's test/unit/testcase.rb so that we don't end
            # up trying to run a spurious unit test method of the same name as our model
            def self.suite
              method_names = public_instance_methods(true)
              tests = method_names.delete_if {|method_name| method_name !~ /^test./ || method_name == "test_whatevers"}
              suite = TestSuite.new(name)
              tests.sort.each do
                |test|
                catch(:invalid_test) do
                  suite << new(test)
                end
              end
              if (suite.empty?)
                catch(:invalid_test) do
                  suite << new("default_test")
                end
              end
              return suite
            end
        end
      end
    end
    

    October 2nd, 2008 @ 05:08 PM

  11. Mike Boone
    Mike Boone
    • Tag changed from 2.0-stable, actionpack, activerecord, bug to 2.0-stable, actionpack, activerecord, bug

    There is still a problem in Rails 2.3.5 with creating a model beginning with 'Test'.

    rails myapp
    cd myapp
    script/generate model testimonial name:string comment:text
    rake db:migrate
    rake test:units

    1) Error: testimonials(ActionView::TestCase):
    TypeError: wrong argument type Class (expected Module)

    8 tests, 1 assertions, 0 failures, 1 errors
    rake aborted!

    January 31st, 2010 @ 03:30 PM

  12. Hery
    Hery
    • Tag changed from 2.0-stable, actionpack, activerecord, bug to 2.0-stable, actionpack, activerecord, activesupport, bug, testcase

    Hi, I found the fix for rails 3 and test-unit using minitest. It is minitest bug :

    In minitest/unit.rb

      def self.test_methods
        methods = public_instance_methods(true).grep(/^test/).map { |m|
          m.to_s
        }.sort
    
        if self.test_order == :random then
          max = methods.size
          methods = methods.sort_by { rand(max) }
        end
    
        methods
      end
    

    You just have to patch your test/test_helper.rb

    class ActiveSupport::TestCase
      # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
      #
      # Note: You'll currently still have to declare fixtures explicitly in integration tests
      # -- they do not yet inherit this setting
      fixtures :all
    
      # Fix minitest bug : all public methods beginning with 'test' are considered as test_methods ... that is not true if we have a resource called testimony
      # testimony_path will not be found and tests will fail!
      def self.test_methods
        methods = public_instance_methods(true).grep(/^test$|^test_/).map { |m|
          m.to_s
        }.sort
    
        if self.test_order == :random then
          max = methods.size
          methods = methods.sort_by { rand(max) }
        end
    
        methods
      end
    
      # Add more helper methods to be used by all tests here...
    
    end
    

    Should it be included in ActiveSupport::TestCase ?

    March 23rd, 2010 @ 10:02 AM

  13. chris finne
    chris finne

    Workaround is pretty easy. Just rename your fixtures file, then associate that odd name with the proper class.

    testimonials.yml => atestimonials.yml

    and in test/test_helper.rb

    class ActiveSupport::TestCase
      ...
      set_fixture_class :atestimonials => Testimonial
      ...
    end
    

    August 16th, 2010 @ 10:55 AM

  14. Mike Boone
    Mike Boone

    @Chris, thanks for the workaround. I tried it and it works.

    I still don't understand why this is a "wontfix". Seems a legitimate bug. Unless there is documentation that states "don't name models with any word that begins with 'Test'"?

    August 28th, 2010 @ 03:36 PM

  15. Ryan Bigg
    Ryan Bigg
    • Tag cleared.
    • Importance changed from to Low

    Automatic cleanup of spam.

    October 9th, 2010 @ 09:44 PM

  16. Jeff Kreeftmeijer
  17. bingbing