【问题标题】:Why is it not possible to use router paths in controller tests?为什么不能在控制器测试中使用路由器路径?
【发布时间】:2012-10-05 17:46:47
【问题描述】:

为什么在 Rails 3 中测试控制器时不能使用路由器路径?

我知道get :new 翻译成{controller: 'sessions', action: 'new'},但为什么signin_path 不能翻译成同样的东西?例如:

# routes.rb
match 'signin', to: 'sessions#new'

# sessions_spec.rb
it "renders the 'new' template" do
  get signin_path
  response.should render_template :new
end

生产:

No route matches {:controller=>"sessions", :action=>"/signin"}

如果能像在应用程序中那样使用路由语法来测试路由就好了,例如 get signin_path 而不是 { get: 'http://app.com/signin/' }

【问题讨论】:

  • 语法应该是match '/signin', to: 'sessions#new'(你省略了前导/)。
  • @cdesrosiers:不正确。但是,公平地说,您建议的代码也可以使用

标签: ruby-on-rails ruby rspec routes


【解决方案1】:

一开始我也很难理解这一点。让我试着解释一下我是如何理解的。

我假设您的引导线如下所示:

describe SessionsController do

在控制器规范中,控制器类是您的主题,而不是路由系统。这就是为什么您应该在控制器中测试单个操作方法,而不是通向它们的路由。换句话说,即使您更改了路由,控制器规范也应该仍然有效。

所以你甚至不应该这样做:

it "renders the 'new' template" do
  get 'http://app.com/signin/'
  response.should render_template :new
end

你应该这样做:

it "renders the 'new' template" do
  get :new
  response.should render_template :new
end

然后,RSpec 会以某种方式确定您要尝试的路线。我注意到,当我搞砸某些东西时,它会给我一个路由错误。

【讨论】:

  • 附带说明,如果您想运行涉及路由 *_path 助手的测试,您可以执行“集成”(也称为“请求”)规范。它们不同于控制器规格。
  • 这是有道理的。公平地说,我已经按照这些思路进行了测试。让我绊倒的是子域受限的路由。例如,我想确定,在不使用子域时,使用子域通过 signup_path 会产生不同的结果。使用get :whatever 会绕过路由器,因此期望会发生变化。我最终将这些测试移到了请求规范中。
  • @Mohamad:我想,但我想在答案中明确。看看这种在控制器规范中更改域的方法:stackoverflow.com/questions/2556627/rails-rspec-set-subdomain
  • 我的方法略有不同:def set_controller_host(host) before { @request.host = host }; end 抱歉,代码的注释格式很糟糕;这就是为什么我把它做成单线!
【解决方案2】:

在你的 routes.rb 中试试这个

match 'signin' => 'sessions#new', :as => :signin

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 2014-06-23
    相关资源
    最近更新 更多