[英]How can I test the request object using a specific URL in application_helper_spec.rb?
I have a method defined in application_helper.rb that returns a canonical URL based on the current request. 我有一个在application_helper.rb中定义的方法,它根据当前请求返回一个规范的URL。 How can I mock or otherwise specify a complete URL for the controller? 如何模拟或以其他方式指定控制器的完整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/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
EDIT : 编辑 :
Ultimately I want to test that canonical_url() returns the proper string for a bunch of different URLs, some with ports, some w/o, some with querystrings, some with paths, etc. Maybe that's overkill, but that is the end goal. 最后,我想测试canonical_url()为一堆不同的URL返回正确的字符串,一些带有端口,一些带有w / o,一些带有查询字符串,一些带有路径等等。也许这太过分了,但这是最终目标。 I would like to both explicitly stub/mock/whatever the initial URL and then explicitly set the expectation in the matcher. 我想明确存根/模拟/无论初始URL,然后在匹配器中显式设置期望。 I would love to be able to do this in one call, ie controller.request.url = 'http://www.foo.com:80/asdf.asdf?asdf=asdf'
or request = ActionController::TestRequest.new :url => 'http://www.foo.com:80/asdf.asdf?asdf=asdf'
but so far I have not found a single "hook" that allows me to do so. 我希望能够在一次调用中完成此操作,即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'
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'
但到目前为止我还没有找到一个允许我这样做的“钩子”。 So that is the solution I'm looking for. 这就是我正在寻找的解决方案。 How do I explicitly define the request URL for a given test. 如何显式定义给定测试的请求URL。
I'd have done: 我做过:
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")
The ultimate cause of this confusion lies in ActionPack: 这种混淆的最终原因在于ActionPack:
eg if you set a port (ActionDispatch::TestRequest) 例如,如果你设置一个端口(ActionDispatch :: TestRequest)
def port=(number)
@env['SERVER_PORT'] = number.to_i
end
eg then you read it (ActionDispatch::Http::URL) 例如,然后你读它(ActionDispatch :: Http :: URL)
def raw_host_with_port
if forwarded = env["HTTP_X_FORWARDED_HOST"]
forwarded.split(/,\s?/).last
else
env['HTTP_HOST'] || "#{env['SERVER_NAME'] || env['SERVER_ADDR']}:#{env['SERVER_PORT']}"
end
end
Setting SERVER_PORT will only take effect if you have no SERVER_NAME, HTTP_X_FORWARDED_HOST or HTTP_HOST already set. 设置SERVER_PORT只有在没有设置SERVER_NAME,HTTP_X_FORWARDED_HOST或HTTP_HOST的情况下才会生效。
My basic workaround for port settings was to add the port to the host - because request.port doesn't do what you want typically. 我对端口设置的基本解决方法是将端口添加到主机 - 因为request.port通常不会执行您想要的操作。
eg to set the port 例如设置端口
request.host = 'example.com:1234'
The real answer is to read the code in ActionPack; 真正的答案是阅读ActionPack中的代码; it's fairly straightforward. 这很简单。
Very late to this party, but found it googling something similar. 这次聚会很晚,但发现谷歌搜索类似的东西。
How about: 怎么样:
allow_any_instance_of(ActionController::TestRequest).to receive(:host).and_return('www.fudge.com')
I appreciate allow_any_instance_of
is sometimes frowned upon, but this does seem to get the job done. 我很欣赏allow_any_instance_of
有时allow_any_instance_of
,但这似乎完成了工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.