Ruby on rails 如何在application\u helper\u spec.rb中使用特定URL测试请求对象?
我在application_helper.rb中定义了一个方法,它根据当前请求返回一个规范URL。如何模拟或以其他方式指定控制器的完整URLRuby on rails 如何在application\u helper\u spec.rb中使用特定URL测试请求对象?,ruby-on-rails,unit-testing,rspec2,helpers,Ruby On Rails,Unit Testing,Rspec2,Helpers,我在application_helper.rb中定义了一个方法,它根据当前请求返回一个规范URL。如何模拟或以其他方式指定控制器的完整URL # spec/helpers/application_helper_spec.rb describe "#canonical_url" do it "should return a path to an asset that includes the asset_host" do # Given: "http://www.foo.com:80/
# spec/helpers/application_helper_spec.rb
describe "#canonical_url" do
it "should return a path to an asset that includes the asset_host" do
# Given: "http://www.foo.com:80/asdf.asdf?asdf=asdf"
helper.canonical_url().should eq("http://www.foo.com/asdf.asdf")
end
end
# app/helpers/application_helper.rb
def canonical_url
"#{request.protocol}#{request.host}#{(request.port == 80) ? "" : request.port_string}#{request.path}"
end
编辑:
最后,我想测试一下,canonical_url()为一组不同的url返回正确的字符串,一些带有端口,一些带有w/o,一些带有查询字符串,一些带有路径,等等。这可能有些过分,但这是最终目标。我想显式地使用stub/mock/不管初始URL是什么,然后在matcher中显式地设置期望值。我希望能够在一次通话中做到这一点,即controller.request.url=http://www.foo.com:80/asdf.asdf?asdf=asdf“
或request=ActionController::TestRequest.new:url=>”http://www.foo.com:80/asdf.asdf?asdf=asdf“
但到目前为止,我还没有找到一个能让我这么做的“钩子”。这就是我正在寻找的解决方案如何明确定义给定测试的请求URL。我应该:
helper.request.stub(:protocol).and_return("http://")
helper.request.stub(:host).and_return("www.foo.com")
helper.request.stub(:port).and_return(80)
helper.request.stub(:port_string).and_return(":80")
helper.request.stub(:path).and_return("/asdf.asdf")
helper.canonical_url.should eq("http://www.foo.com/asdf.asdf")
造成这种混乱的最终原因在于ActionPack:
- ActionDispatch::TestRequest
- ActionDispatch::Http::URL
request.host = 'example.com:1234'
真正的答案是阅读ActionPack中的代码;这相当简单。很晚才参加这个聚会,但发现它在谷歌上搜索类似的东西 那么:
allow_any_instance_of(ActionController::TestRequest).to receive(:host).and_return('www.fudge.com')
我很感激
allow\u任何的实例有时都会遭到反对,但这似乎确实完成了任务。我尝试过它的一个变体,但使用了controller.request.mock(:protocol){'http://'}
,但出现了一个错误,说请求对象上没有定义mock。我可以用你的例子再试一次,但我真的很想在每个测试运行之前将其设置为单个字符串。我要抱怨的是,这种方法根本不起作用,因为我想要剥离的查询字符串部分没有在任何地方指定。但这在理想情况下由Rails内部构件IRL决定,#path
应该只返回不带查询字符串的路径。所以,你是对的。有时我跑过“那是框架的工作”这一行,却没有意识到这一点。。。我想知道是否有一种方法可以一次指定所有的URL。根据先验知识,我看不到任何方法可以实现这一点。但我会记住这个问题:我真的不在乎我传递的URL是什么。它不需要是应用程序自己的URL,因为规范的URL方法应该适用于任何给定的URL。但是,我确实希望在测试之前显式定义它,而不是依赖于ActionController::TestRequest的默认设置。谢谢您的后续回答。下次我将尝试这种方法。
request.host = 'example.com:1234'
allow_any_instance_of(ActionController::TestRequest).to receive(:host).and_return('www.fudge.com')