Rails: How to test code in the lib/ directory?

I have a model which gets its data from a parser object. I'm thinking that the parser class should live in the lib/ directory (although I could be persuaded that it should live soewhere else). The question is: Where should my unit tests for the parser class be? And how do I ensure that they are run each time I run rake test?


Solution 1:

In the Rails application I'm working on, I decided to just place the tests in the test\unit directory. I will also nest them by module/directory as well, for example:

lib/a.rb   => test/unit/a_test.rb
lib/b/c.rb => test/unit/b/c_test.rb

For me, this was the path of last resistance, as these tests ran without having to make any other changes.

Solution 2:

Here's one way:

Create lib/tasks/test_lib_dir.rake with the following

namespace :test do

  desc "Test lib source"
  Rake::TestTask.new(:lib) do |t|    
    t.libs << "test"
    t.pattern = 'test/lib/**/*_test.rb'
    t.verbose = true    
  end

end

Mimic the structure of your lib dir under the test dir, replacing lib code with corresponding tests.

Run rake test:lib to run your lib tests.

If you want all tests to run when you invoke rake test, you could add the following to your new rake file.

lib_task = Rake::Task["test:lib"]
test_task = Rake::Task[:test]
test_task.enhance { lib_task.invoke }

Solution 3:

I was looking to do the same thing but with rspec & autospec and it took a little digging to figure out just where they were getting the list of directories / file patterns that dictated which test files to run. Ultimately I found this in lib/tasks/rspec.rake:86

  [:models, :controllers, :views, :helpers, :lib, :integration].each do |sub|
    desc "Run the code examples in spec/#{sub}"
    Spec::Rake::SpecTask.new(sub => spec_prereq) do |t|
      t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
      t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
    end
  end

I had placed my tests in a new spec/libs directory when the rpsec.rake file was configured to look in spec/lib. Simply renaming libs -> lib did the trick!