如何在 rspec 中编写 Rails 3.1 引擎控制器测试? [英] How do I write a Rails 3.1 engine controller test in rspec?

查看:26
本文介绍了如何在 rspec 中编写 Rails 3.1 引擎控制器测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经用命名空间 Posts 编写了一个 Rails 3.1 引擎.因此,我的控制器在 app/controllers/posts/中,我的模型在 app/models/posts 等中.我可以很好地测试模型.一种模型的规格看起来像...

I have written a Rails 3.1 engine with the namespace Posts. Hence, my controllers are found in app/controllers/posts/, my models in app/models/posts, etc. I can test the models just fine. The spec for one model looks like...

module Posts
  describe Post do
    describe 'Associations' do
      it ...
      end

...一切正常.

但是,控制器的规格不起作用.Rails 引擎安装在/posts,而控制器是 Posts::PostController.因此,测试寻找控制器路由为帖子/帖子.

However, the specs for the controllers do not work. The Rails engine is mounted at /posts, yet the controller is Posts::PostController. Thus, the tests look for the controller route to be posts/posts.

  describe "GET index" do
    it "assigns all posts as @posts" do
      Posts::Post.stub(:all) { [mock_post] }
       get :index
       assigns(:posts).should eq([mock_post])
    end
  end

产生...

  1) Posts::PostsController GET index assigns all posts as @posts
     Failure/Error: get :index
     ActionController::RoutingError:
     No route matches {:controller=>"posts/posts"}
     # ./spec/controllers/posts/posts_controller_spec.rb:16

我在测试应用程序的路由文件中尝试了各种技巧......:命名空间等,但无济于事.

I've tried all sorts of tricks in the test app's routes file... :namespace, etc, to no avail.

我该如何进行这项工作?似乎不会,因为引擎将控制器放在/posts,但命名空间将控制器放在/posts/posts 以进行测试.

How do I make this work? It seems like it won't, since the engine puts the controller at /posts, yet the namespacing puts the controller at /posts/posts for the purpose of testing.

推荐答案

我假设您正在使用一个虚拟的 rails 应用程序测试您的引擎,就像由 enginex.

I'm assuming you're testing your engine with a dummy rails app, like the one that would be generated by enginex.

您的引擎应该安装在虚拟应用程序中:

Your engine should be mounted in the dummy app:

spec/dummy/config/routes.rb:

Dummy::Application.routes.draw do
  mount Posts::Engine => '/posts-prefix'
end

我的第二个假设是您的引擎是孤立的:

My second assumption is that your engine is isolated:

lib/posts.rb 中:

module Posts
  class Engine < Rails::Engine
    isolate_namespace Posts
  end
end

我不知道这两个假设是否真的需要,但我自己的引擎就是这样构建的.

I don't know if these two assumptions are really required, but that is how my own engine is structured.

解决方法很简单,而不是这个

The workaround is quite simple, instead of this

get :show, :id => 1

使用这个

get :show, {:id => 1, :use_route => :posts}

:posts 符号应该是引擎的名称,而不是它的安装路径.

The :posts symbol should be the name of your engine and NOT the path where it is mounted.

这是有效的,因为 get 方法参数直接传递给 ActionDispatch::Routing::RouteSet::Generator#initialize(定义 here),依次使用 @named_routeRack::Mount::RouteSet#generate 的正确路线(参见 这里这里).

This works because the get method parameters are passed straight to ActionDispatch::Routing::RouteSet::Generator#initialize (defined here), which in turn uses @named_route to get the correct route from Rack::Mount::RouteSet#generate (see here and here).

深入 Rails 内部很有趣,但很耗时,我不会每天都这样做 ;-) .

Plunging into the rails internals is fun, but quite time consuming, I would not do this every day ;-) .

HTH

这篇关于如何在 rspec 中编写 Rails 3.1 引擎控制器测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆