为 Rails 3 插件生成测试路由时出错?

发布于 2024-11-04 05:01:03 字数 1293 浏览 1 评论 0原文

我正在尝试为插件“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

知道我做错了什么导致我无法访问路由吗?我已经研究了好几天并搜索了很多文档,但无济于事。感谢您的帮助!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

死开点丶别碍眼 2024-11-11 05:01:03

我通过遵循 "创建的基础知识,在 Rails 3.1.0.rc1 和 Ruby 1.9.2 上工作Rails 插件” 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__), '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

最后,我们的测试通过:

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

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
猫九 2024-11-11 05:01:03

调试此问题的最佳选择是这样做,

rake <task> --trace

这将使您更好地了解导致 _routes 错误的原因(即行号)。

Your best bet for debugging this is to do

rake <task> --trace

This will give you a much better idea (i.e. a line number) on what is causing the _routes error.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文