我正在使用 Test::Unit 测试我的 Rails 应用程序。我经常遇到的一个问题是测试我尚未找到解决方案的应用程序的路由。
目前,我正在开发一个应用程序,它使用 Basecamp 样式的子域来区分帐户。
有些路由需要子域
constraints(SubdomainRoute) do
get "/login" => "user_sessions#new", :as => :login
get "/logout" => "user_sessions#destroy", :as => :logout
...
end
以及只能在没有子域的情况下才能访问的路由
constraints(NoSubdomainRoute) do
match "/" => "public#index", :as => :public_root
match "/signup" => "public#signup", :as => :signup
...
end
类 SubdomainRoute 定义为:
class SubdomainRoute
def self.matches?(request)
request.subdomain.present? && request.subdomain != "api" && request.subdomain != "www"
end
end
NoSubdomainRoute 类的作用恰恰相反。
路由按预期工作,但如何使用 Test::Unit 测试它们?
在功能测试中,我可以做类似的事情
assert_routing "/signup", :controller => "public", :action => "signup"
但我无法提供子域,所以实际上这只是测试 Rails 内部结构,对测试我的应用程序没有任何帮助。在这种情况下,我想测试的是 signup_path/signup_url 是否可以在有或没有子域的情况下访问。
在代码中,像这样
assert_raise(ActionDispatch::RoutingError) { get "http://account.test.host/signup" }
get "http://www.test.host/signup"
assert_response :success
get 在这种情况下不起作用,因为 Test::Unit 将整个 URL 视为 Controller 的操作(... :action => "http://account.test.host/signup")。
设置
@request.host = "subdomain.test.host"
仅影响您的内部 Controller 代码(例如,通过从主机中提取子域来获取当前帐户)但在这种情况下不会影响路由。
我不知道在集成测试中情况是否有任何不同。
所以两个主要问题是
- 一般要测试的路线在哪里?
- 他们如何针对这种特殊情况进行测试?
我愿意尝试不同的方法(Capybara 和 friend ),但我不想切换我的测试框架(已经有我的 RSpec-time),因为我对 Test::Unit 非常满意。
在此先致谢并致以亲切的问候!
最佳答案
实际上,解决方案非常简单,因为 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" }
向 assert_routing 提供 URL 的功能已添加到 here 中。
搜索策略:
- 发现
assert_routing
定义在actionpack
gem 安装 gemedit
gem edit Action 包
- 打开
lib/action_dispatch/testing/assertions/routing.rb
发现recognized_request_for
是处理路径的处理 - 通过 GitHub 打开文件,然后选择“Blame”以查看哪个提交添加了该功能
关于ruby-on-rails - 在 Rails 3 中测试子域约束路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6323579/