在Rails 3中测试子域约束路由

Mic*_*nek 20 testing subdomain ruby-on-rails

我正在用Test :: Unit测试我的Rails应用程序.我经常遇到的一个问题是测试我的应用程序的路线,但我还没有找到解决方案.

目前,我正在开发一个使用Basecamp风格子域来区分帐户的应用程序.

有些路由需要子域

constraints(SubdomainRoute) do
  get  "/login" => "user_sessions#new", :as => :login
  get  "/logout" => "user_sessions#destroy", :as => :logout
  ...
end
Run Code Online (Sandbox Code Playgroud)

以及只能在没有子域的情况下访问的路由

constraints(NoSubdomainRoute) do
  match "/" => "public#index", :as => :public_root
  match "/signup" => "public#signup", :as => :signup
  ...
end
Run Code Online (Sandbox Code Playgroud)

SubdomainRoute类定义为:

class SubdomainRoute
  def self.matches?(request)
    request.subdomain.present? && request.subdomain != "api" && request.subdomain != "www"
  end
end
Run Code Online (Sandbox Code Playgroud)

NoSubdomainRoute类恰恰相反.

路由按预期工作,但如何使用Test :: Unit测试?

在功能测试中,我可以做类似的事情

assert_routing "/signup", :controller => "public", :action => "signup"
Run Code Online (Sandbox Code Playgroud)

但我无法提供子域,所以实际上只测试Rails内部,这对测试我的应用程序没有任何帮助.在这种情况下我想要测试的是,无论有没有子域,都可以访问signup_path/signup_url.

在代码中,这样的东西

assert_raise(ActionDispatch::RoutingError) { get "http://account.test.host/signup" }
get "http://www.test.host/signup"
assert_response :success
Run Code Online (Sandbox Code Playgroud)

get在这种情况下不起作用,因为Test :: Unit将整个URL视为控制器的动作(...:action =>"http://account.test.host/signup").

设置

@request.host = "subdomain.test.host"
Run Code Online (Sandbox Code Playgroud)

只会对您的内部控制器代码产生影响(例如,通过从主机中提取子域来获取当前帐户),但在这种情况下不会影响路由.

我不知道集成测试中的情况是否有任何不同.

所以两个主要问题是

  1. 一般来说,路线在哪里
  2. 他们如何针对这一特殊情况进行测试?

我想尝试不同的方法(Capybara和朋友),但我不想切换我的测试框架(已经有我的RSpec时间),因为我对Test :: Unit非常满意.

在此先感谢您的亲切问候!

jus*_*see 13

其实解决方法很简单,因为assert_routing 支持URL:

assert_routing "http://subdomain.example.com/login",
  { :controller => "user_sessions", :action => "new" }

assert_routing "http://www.example.com/signup",
  { :controller => "public", :action => "signup" }
Run Code Online (Sandbox Code Playgroud)

此处添加为assert_routing提供URL的功能.

搜索策略:

  • 发现的assert_routing定义是actionpack
  • gem install gemedit
  • gem edit actionpack
  • 打开lib/action_dispatch/testing/assertions/routing.rb并找到recognized_request_for处理路径处理的内容
  • 通过GitHub打开文件,并选择"Blame"以查看添加该功能的提交


Mat*_*ito 0

我会测试你的班级的功能,而不一定是路线本身。我觉得这本质上是在测试 Rails。

您知道,如果您将类传递给约束块,如果您定义了 .matches,它将起作用?方法。因此,只需测试您是否获得了预期的逻辑即可。