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!
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With