【问题标题】:Rails4 - Testing - URLGenerationError: No route matchesRails4 - 测试 - URLGenerationError:没有路由匹配
【发布时间】:2025-12-12 13:30:03
【问题描述】:

我在 SO 中阅读了很多其他问题,但没有一个可以解决我的问题(它们似乎都与参数有关)。我希望有人可以帮助我。

执行我的控制器测试我收到这条消息:

ActionController::UrlGenerationError: No route matches 
    {:action=>"/login", :controller=>"sessions"}
test/controllers/sessions_controller_test.rb:6:in `block in 
    <class:SessionsControllerTest>'

我的rake routes 看起来像这样:

Prefix Verb   URI Pattern       Controller#Action
login  GET    /login(.:format)  sessions#new
       POST   /login(.:format)  sessions#create
logout DELETE /logout(.:format) sessions#destroy

我的测试本身就是这个:

test "should get new" do
    puts 'debug: ' + login_path
    get login_path
    assert_response :success
end

puts 调试行打印:debug: /login

当我在网络浏览器中转到localhost:3000/login 时,它会正确加载页面并调试它使用的信息:

controller: sessions
action: new

知道为什么测试没有正确重定向到new 操作,而是寻找不存在的操作/login?谢谢!

编辑:解决方案

按照下面的答案,我找到了解释整个问题的链接:

http://blog.bigbinary.com/2016/04/19/changes-to-test-controllers-in-rails-5.html

在 Rails4(我正在使用)上,控制器测试使用 ActionController::TestCase,其中必须使用 get :new 而不是 get login_url(这在集成测试中是可以的)。

【问题讨论】:

  • 你为什么用get login_path而不是get :new
  • 跟随railstutorial.org/book/basic_login 尝试了您的代码并且工作正常。谢谢!
  • 我想知道它是否应该适用于教程风格。
  • 不应该。那本书现在已经过时了;如果您使用的 Rails 版本比本书更新,则无法保证其中的 任何内容 都能正常工作。

标签: ruby-on-rails ruby-on-rails-4 testing routes


【解决方案1】:

getpostdelete 等测试方法都假定您传递给它们的任何参数都是被测试控制器内的action 的名称。所以,这个调用有效:

get :new

因为它生成url_for(:controller =&gt; :sessions, :action =&gt; :new)。此调用不会:

get '/login'

因为它会生成url_for(:controller =&gt; :sessions, :action =&gt; '/login')

使用符号形式。

【讨论】:

    【解决方案2】:

    使用 url 进行测试的正确方法是写 get login_url 而不是 get login_path

    这是因为测试过程不在浏览器中运行,所以path 变量只包含/login,这是一个相对路径(当您通过浏览器看到它时有效因为路径被附加)。另一方面,url 变量是一个通用资源定位器,因此它是一个绝对路径,它会起作用。

    【讨论】:

    • 这样我得到:No route matches {:action=&gt;"http://test.host/login", :controller=&gt;"sessions"}
    • @PacoAbato Erm,你熟悉test.host吗?
    • 我假设它是本地主机。无论如何是一个失败的测试:ActionController::UrlGenerationError: No route matches {:action=&gt;"http://test.host/login", :controller=&gt;"sessions"}
    • @PacoAbato 如果出现test.host,则表明您的项目有问题。虽然您已经找到了一个解决方案(这不是最好的 IMO,因为测试应该通过控制器操作验证路由),但我建议您解决此问题以避免将来可能相关的错误。
    • @ArtOfCode 我并不是说您的解决方案不好。但该测试的重点是查看绝对 url 是否打开了正确的控制器。使用您的方法,当该人运行 SessionsControllerTest 文件时,它已经暗示控制器是会话,并且由于您直接调用 :new ,所以它变得很明显。 PacoAbato 对此我不确定,如果 ArtOfCode 说没问题,那一定是。
    最近更新 更多