2

环境:

  • 红宝石 1.9.3p194
  • 导轨 3.2.8

当我创建 rails 的可安装引擎“MyEngine”并在“post”模型上生成脚手架时,即使我通过以下步骤进行了修改,功能测试也会失败:

  1. 通过以下方式创建可安装引擎:

    $ rails plugin new my_engine --mountable
    $ cd my_engine
    $ rake db:create; rake db:migrate; rake db:setup
    $ rails g scaffold post name zip
    $ rake db:migrate
    
  2. 'rake test' 失败如下:

    $ rake test
    NoMethodError: undefined method `posts' for
    <MyEngine::PostsControllerTest:0xacd1fa4> 
    ...my_engine/test/functional/my_engine/posts_controller_test.rb:6:in
    'block in <class:PostsControllerTest>'
    ...
    
  3. 根据https://github.com/rails/rails/issues/4971http://edgeguides.rubyonrails.org/engines.html“5.1功能测试”,我修改了两处:

    1. 将以下标志附加到 test/test_helper.rb:

      class ActiveSupport::TestCase
        fixtures :all
      end
      

      由于发生“找不到表'my_engine_posts'”错误,手动重新创建测试数据库如下:

      $ (export RAILS_ENV=test; rake db:drop; rake db:create; rake db:migrate; rake db:setup)

    2. 修改 test/functional/my_engine/posts_controller_test.rb 为:

       module MyEngine
         class PostsControllerTest < ActionController::TestCase
           setup do
             @post = my_engine_posts(:one)
           end       ^^^^^^^^^^
           ...
           test "should get index" do
             get :index, use_route: :my_engine
                       ^^^^^^^^^^^^^^^^^^^^^^^
      

但是,在以下步骤中仍然 rake 测试失败:

test_should_create_post(MyEngine::PostsControllerTest): NoMethodError: undefined method `post_path' for...

其中“post_path”命名路由用于脚手架生成的功能测试。我认为命名路线看起来不错,因为:

$ rake app:routes
my_engine  /my_engine MyEngine::Engine

Routes for MyEngine::Engine:
    posts GET    /posts(.:format)          my_engine/posts#index
          POST   /posts(.:format)          my_engine/posts#create  new_post GET    /posts/new(.:format)      my_engine/posts#new
edit_post GET    /posts/:id/edit(.:format) my_engine/posts#edit
     post GET    /posts/:id(.:format)      my_engine/posts#show
          PUT    /posts/:id(.:format)      my_engine/posts#update
          DELETE /posts/:id(.:format)      my_engine/posts#destroy

有趣的是,rails app(不是插件)脚手架生成功能测试的类似步骤(当然!)如下:

 $ rails new my_app
 $ cd my_app/
 $ rake db:create; rake db:migrate; rake db:setup
 $ rails g scaffold post name zip
 $ rake  db:migrate
 $ rake test

如果有人帮助我如何在可安装引擎上通过脚手架生成的功能测试,我将非常感激!

4

3 回答 3

3

通过将其添加到解决test/test_helper.rb

class ActionController::TestCase
  include MyEngine::Engine.routes.url_helpers
end

更改MyEngine为您自己的引擎名称。


最初的想法来自http://www.matthewratzloff.com/blog/2011/09/21/testing-routes-with-rails-3-1-engines/#comment-1572中概述的 RSpec 解决方案

于 2013-01-31T15:16:40.820 回答
1

我此时的结论是不要在功能测试中使用命名路由。例如:

assert_redirected_to posts_path
  ↓
assert_redirected_to controller: 'my_engine/posts'

我知道像http://edgeguides.rubyonrails.org/engines.html “6.3 Routes”提到的那样,有像 main_app 和/或 my_engine 这样的路由代理。它适用于控制器和视图,但不适用于功能测试(尽管在常规应用程序的功能测试中支持命名路由,而不是可安装引擎)。带有路由代理的命名路由可能可以在测试中使用,但我此时找不到方法。

于 2012-09-10T09:01:07.360 回答
0

尝试将这些添加到生成的 test_helper.rb 中:

def post_path(post)
  "/my_engine/posts/#{post.to_param}"
end

def posts_path
  '/my_engine/posts'
end

它对我有用。

于 2012-10-07T10:57:47.770 回答