Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error generating test routes for Rails 3 plugin?

I'm trying to develop tests for plugin "foobar" that modifies some of the standard Rails helpers. In vendor/plugins/foobar/test/foobar_test.rb, I have the following:

# create the test model
class Thing < ActiveRecord::Base
end

# create the test controller, which renders the included index template
class ThingsController < ActionController::Base
  def index
    @things = Thing.all
    format.html { render(:file => 'index') }
  end

  def destroy
    @thing = Thing.find(params[:id])
    @thing.destroy
    format.html { render(:file => 'index') }
  end
end

# confirm that the test environment is working correctly
class ThingsTest < ActiveSupport::TestCase
  test "model is loaded correctly" do
    assert_kind_of Thing, Thing.new
  end
end

# confirm that the controller and routes are working correctly
class ThingsControllerTest < ActionController::TestCase
  test "should load index" do
    with_routing do |set|
      set.draw do
        resources :things, :only => [:index, :destroy]
      end

      get :index
      assert_response :success
    end
  end
end

When I run rake, I get the following output:

test_should_load_index(ThingsControllerTest):
NameError: undefined local variable or method `_routes' for ThingsController:Class

Any idea what I'm doing wrong that is preventing me from accessing the routes? I've been at this for days and scoured much documentation, to no avail. Thanks for the help!

like image 387
Malefactor Avatar asked Apr 28 '11 13:04

Malefactor


1 Answers

I got things to work on Rails 3.1.0.rc1 with Ruby 1.9.2, by following "The Basics of Creating Rails Plugins" Rails Guide and correcting the code whenever it exploded due to an incompatibility.

I started by running:

Code$ rails new tester
Code$ cd tester
tester$ rails generate plugin foobar --with-generator

Then modifying the generated code to obtain these files in addition to the default ones:

# vendor/plugins/foobar/init.rb
require 'foobar'

# vendor/plugins/foobar/lib/foobar.rb

%w{ models controllers helpers }.each do |dir|
  path = File.join(File.dirname(__FILE__), 'app', dir)
  $LOAD_PATH << path
  ActiveSupport::Dependencies.autoload_paths << path
  ActiveSupport::Dependencies.autoload_once_paths.delete(path)
end

# I'm not entirely sure this is the best way to add our plugin's views
# to the view search path, but it works
ActionController::Base.view_paths = 
  ActionController::Base.view_paths + 
  [ File.join(File.dirname(__FILE__), 'app', 'views') ]

<!-- vendor/plugins/foobar/lib/app/views/things/index.html.erb -->
<h1>Listing things</h1>

<table>
  <tr>
    <th>Name</th>
    <th></th>
  </tr>

<% @things.each do |thing| %>
  <tr>
    <td><%= thing.name %></td>
    <td><%= link_to 'Destroy', thing, confirm: 'Are you sure?', method: :delete %></td>
  </tr>
<% end %>
</table>

# vendor/plugins/foobar/test/database.yml

sqlite:
  :adapter: sqlite
  :dbfile: vendor/plugins/foobar/test/foobar_plugin.sqlite.db

sqlite3:
  :adapter: sqlite3
  :database: vendor/plugins/foobar/test/foobar_plugin.sqlite3.db

postgresql:
  :adapter: postgresql
  :username: postgres
  :password: postgres
  :database: foobar_plugin_test
  :min_messages: ERROR

mysql:
  :adapter: mysql
  :host: localhost
  :username: root
  :password: password
  :database: foobar_plugin_test

# vendor/plugins/foobar/test/schema.rb

ActiveRecord::Schema.define(:version => 0) do
  create_table :things, :force => true do |t|
    t.string :name
    t.datetime :created_at
    t.datetime :updated_at
  end
end

# vendor/plugins/foobar/test/test_helper.rb

ENV['RAILS_ENV'] = 'test'
ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..'

require 'test/unit'
require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config/environment.rb'))

def load_schema
  config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
  ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")

  db_adapter = ENV['DB']

  # no db passed, try one of these fine config-free DBs before bombing.
  db_adapter ||=
    begin
      require 'rubygems'
      require 'sqlite'
      'sqlite'
    rescue MissingSourceFile
      begin
        require 'sqlite3'
        'sqlite3'
      rescue MissingSourceFile
      end
    end

  if db_adapter.nil?
    raise "No DB Adapter selected. Pass the DB= option to pick one, or install Sqlite or Sqlite3."
  end

  ActiveRecord::Base.establish_connection(config[db_adapter])
  load(File.dirname(__FILE__) + "/schema.rb")
  require File.dirname(__FILE__) + '/../init'
end

load_schema

# vendor/plugins/foobar/test/foobar_test.rb
require File.dirname(__FILE__) + '/test_helper' 

# create the test model
class Thing < ActiveRecord::Base
end

# create the test controller, which renders the included index template
class ThingsController < ActionController::Base
  def index
    @things = Thing.all
    respond_to do |format|
      format.html # index.html.erb
    end
  end

  def destroy
    @thing = Thing.find(params[:id])
    @thing.destroy
    respond_to do |format|
      format.html { redirect_to things_url }
    end
  end
end

# confirm that the test environment is working correctly
class ThingsTest < ActiveSupport::TestCase
  test "schema has loaded correctly" do
    assert_equal [], Thing.all
  end

  test "model is loaded correctly" do
    assert_kind_of Thing, Thing.new
  end
end

# confirm that the controller and routes are working correctly
class ThingsControllerTest < ActionController::TestCase
  test "should load index" do
    with_routing do |set|
      set.draw do
        resources :things, :only => [:index, :destroy]
      end

      get :index
      assert_response :success
    end
  end
end

And finally, our test passes:

tester$ cd vendor/plugins/foobar/
foobar$ rake
-- create_table(:things, {:force=>true})
   -> 0.0059s
-- initialize_schema_migrations_table()
   -> 0.0002s
-- assume_migrated_upto_version(0, ["db/migrate"])
   -> 0.0003s
Loaded suite /Users/nick/.rvm/gems/ruby-1.9.2-p0/gems/rake-0.9.2/lib/rake/rake_test_loader
Started
...
Finished in 0.091642 seconds.

3 tests, 3 assertions, 0 failures, 0 errors, 0 skips
like image 186
Nick Desjardins Avatar answered Oct 14 '22 03:10

Nick Desjardins