如何使用 application_helper_spec.rb 中的特定 URL 测试请求对象?

发布于 2024-11-17 12:44:18 字数 1004 浏览 1 评论 0原文

我在 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/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 返回正确的字符串,有些带有端口,有些没有,有些带有查询字符串,有些带有路径等。也许这就是矫枉过正,但这就是最终目标。我想显式存根/模拟/无论初始 URL,然后在匹配器中显式设置期望。我希望能够在一次调用中完成此操作,即 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。

I have a method defined in application_helper.rb that returns a canonical URL based on the current request. How can I mock or otherwise specify a complete URL for the controller?

# 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. I would like to both explicitly stub/mock/whatever the initial URL and then explicitly set the expectation in the matcher. I would love to be able to do this in one call, i.e. 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. So that is the solution I'm looking for. How do I explicitly define the request URL for a given test.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尘世孤行 2024-11-24 12:44:19

我会这样做:

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")

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")
酒解孤独 2024-11-24 12:44:19

这种混乱的最终原因在于 ActionPack:

  • ActionDispatch::TestRequest
  • ActionDispatch::Http::URL

例如如果您设置了一个端口(ActionDispatch::TestRequest),

def port=(number)
  @env['SERVER_PORT'] = number.to_i
end

例如,然后您读取了它(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

只有在您尚未设置 SERVER_NAME、HTTP_X_FORWARDED_HOST 或 HTTP_HOST 时,设置 SERVER_PORT 才会生效。

我对端口设置的基本解决方法是将端口添加到主机 - 因为 request.port 通常不会执行您想要的操作。

例如设置端口

request.host = 'example.com:1234'

真正的答案是阅读ActionPack中的代码;这相当简单。

The ultimate cause of this confusion lies in ActionPack:

  • ActionDispatch::TestRequest
  • ActionDispatch::Http::URL

e.g. if you set a port (ActionDispatch::TestRequest)

def port=(number)
  @env['SERVER_PORT'] = number.to_i
end

e.g. then you read it (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.

My basic workaround for port settings was to add the port to the host - because request.port doesn't do what you want typically.

e.g. to set the port

request.host = 'example.com:1234'

The real answer is to read the code in ActionPack; it's fairly straightforward.

屋顶上的小猫咪 2024-11-24 12:44:19

参加这个聚会已经很晚了,但发现它在谷歌上搜索了类似的东西。

怎么样:

allow_any_instance_of(ActionController::TestRequest).to receive(:host).and_return('www.fudge.com')

我很欣赏 allow_any_instance_of 有时会被人皱眉,但这似乎确实可以完成工作。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文