我正在尝试为插件“foobar”开发测试,修改一些标准的Rails助手.在vendor / plugins / foobar / test / foobar_test.rb中,我有以下内容:
# 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
当我运行rake时,我得到以下输出:
test_should_load_index(ThingsControllerTest): NameError: undefined local variable or method `_routes' for ThingsController:Class
知道我做错了什么阻止我访问路线?我已经在这里待了好几天并且搜索了很多文档,但都无济于事.谢谢您的帮助!
解决方法
我使用Ruby 1.9.2在Rails 3.1.0.rc1上工作,遵循
“The Basics of Creating Rails Plugins” Rails指南并在因不兼容而爆炸时更正代码.
我开始跑步:
Code$rails new tester Code$cd tester tester$rails generate plugin foobar --with-generator
# 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__),'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,:destroy] end get :index assert_response :success end end end
最后,我们的测试通过:
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