Ruby-on-rails 如何更改默认的“www.example.com”域以在 Rails 中进行测试?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/598933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:00:55  来源:igfitidea点击:

How do I change the default "www.example.com" domain for testing in rails?

ruby-on-railsrspec

提问by Denis Hennessy

I have a rails application which acts differently depending on what domain it's accessed at (for example www.myapp.com will invoke differently to user.myapp.com). In production use this all works fine but my test code always sees a hostname of "www.example.com".

我有一个 rails 应用程序,它的行为取决于它访问的域(例如 www.myapp.com 将与 user.myapp.com 不同地调用)。在生产中使用这一切正常,但我的测试代码总是看到“www.example.com”的主机名。

Is there a clean way of having a test specify the hostname it's pretending to access?

是否有一种干净的方法可以让测试指定它假装访问的主机名?

采纳答案by jcrossley3

@request.host = 'user.myapp.com'

回答by deivid

I think all answers are incomplete here... To enumerate all possible cases:

我认为这里的所有答案都不完整......列举所有可能的情况:

  • Integration Specs(inheriting from ActionDispatch::IntegrationTest):

    host! "my.awesome.host"
    

    See the docs, section 5.1 Helpers Available for Integration Tests.

  • Controller Specs(inheriting from ActionController::TestCase)

    @request.host = 'my.awesome.host'
    

    See the docs, section 4.4 Instance Variables Available.

  • Feature Specs(through Capybara)

    Capybara.default_host = "http://my.awesome.host"
    # Or to configure domain for route helpers:
    default_url_options[:host] = "my.awesome.host"
    

    From @AminAriana's answer

  • View Specs(inheriting from ActionView::TestCase)

    @request.host = 'my.awesome.host'
    

    ...or through RSpec:

    controller.request.host = "my.awesome.host"
    

    See the rspec-railsview spec docs.

  • 集成规范(继承自ActionDispatch::IntegrationTest):

    host! "my.awesome.host"
    

    请参阅文档,第 5.1 节可用于集成测试的帮助程序

  • 控制器规范(继承自ActionController::TestCase

    @request.host = 'my.awesome.host'
    

    请参阅文档的4.4 节可用的实例变量

  • 功能规格(通过 Capybara)

    Capybara.default_host = "http://my.awesome.host"
    # Or to configure domain for route helpers:
    default_url_options[:host] = "my.awesome.host"
    

    来自@AminAriana 的回答

  • 查看规格(继承自ActionView::TestCase

    @request.host = 'my.awesome.host'
    

    ...或通过 RSpec:

    controller.request.host = "my.awesome.host"
    

    请参阅rspec-rails视图规范文档

回答by Amin Ariana

Feature specs

功能规格

In Feature specs, host! has been deprecated. Add these to your spec_helper.rb:

在功能规格中,主机!已被弃用。将这些添加到您的spec_helper.rb

# Configure Capybara expected host
Capybara.app_host = "http://test.domain"

# Configure actual routes host during test
before(:each) do
  default_url_options[:host] = <myhost>
end

Request specs

请求规格

In Request specs, keep using host! :

在请求规范中,继续使用主机!:

host! "test.domain"

Alternatively refactor it in before(:each)blocks, or configure it globally for request specs at spec_helper.rblevel:

或者在before(:each)块中重构它,或在spec_helper.rb级别为请求规范全局配置它:

RSpec.configure do |config|
  config.before(:each, type: :request) do
    host! "test.domain"
  end
end

回答by mastaBlasta

Another thing to remember is to make sure to use the correct session instanceso that you can properly encapsulate the url helpers.

要记住的另一件事是确保使用正确的会话实例,以便您可以正确封装 url 助手。

Integration tests provide you with a default session. You can call all session methodsdirectly from your tests

集成测试为您提供默认会话。您可以直接从测试中调用所有会话方法

test "should integrate well" do
  https!
  get users_path
  assert_response :success
end

All these helpers are using the default session instance, which if not changed, goes to "www.example.com". As has been mentioned the host can be changed by doing host!("my.new.host")

所有这些助手都使用默认会话实例,如果没有更改,则转到“www.example.com”。如前所述,可以通过执行 host!("my.new.host") 更改主机

If you create multiple sessions using the open_session method, you must ALWAYS use that instance to call the helper methods. This will properly encapsulate the request. Otherwise rails will call the default session instance which may use a different host:

如果您使用 open_session 方法创建多个会话,则必须始终使用该实例来调用辅助方法。这将正确封装请求。否则 rails 将调用可能使用不同主机的默认会话实例:

test "should integrate well" do
  sess = open_session
  sess.host! "my.awesome.host"
  sess.get users_url             #=> WRONG! will use default session object to build url.
  sess.get sess.users_url        #=> Correctly invoking url writer from my custom session with new host.
  sess.assert_response :success
end

If you intended to use the default session object, then you'll have to alter that host as well:

如果您打算使用默认会话对象,那么您还必须更改该主机:

test "should integrate well" do
  sess = open_session
  sess.host! "my.awesome.host"
  host! sess.host              #=> Set default session host to my custom session host.
  sess.get users_url
end 

回答by Dave Ray

I believe you can modify the HTTP_HOSTor SERVER_NAMEenvironment vars to change the request that goes to the router:

我相信您可以修改HTTP_HOSTSERVER_NAME环境变量来更改发送到路由器的请求:

ENV['SERVER_NAME'] = "user.myapp.com"

See raw_host_with_portin actionpack/lib/action_controller/request.rb.

raw_host_with_portActionPack的/ lib目录/ action_controller / request.rb

回答by Ian

@request.host = 'user.myapp.com'is not right. should use host!('user.myapp.com')

@request.host = 'user.myapp.com'是不正确的。应该使用host!('user.myapp.com')

回答by David Hempy

I tried many variations of @request.host, host!, and post path, args, {'SERVER_NAME' => my_secret_domain}without success, both as controller tests and feature tests. Very aggravating, as so many others reported success with those approaches.

我尝试了, 和 的许多变体@request.host,但都没有成功,无论是作为控制器测试还是功能测试。非常令人恼火,因为许多其他人报告说这些方法取得了成功。host!post path, args, {'SERVER_NAME' => my_secret_domain}

The solution for me was:

我的解决方案是:

request.headers["SERVER_NAME"] = my_secret_domain
post path, args

I'm running ruby 2.1.5p273, rspec 3.1.7 and Rails 4.2.0

我正在运行 ruby​​ 2.1.5p273、rspec 3.1.7 和 Rails 4.2.0

回答by Hendra Uzia

Yet another answer:

还有一个答案:

request.host = "user.myapp.com"

I know it resembles the correct answer, but please bear with me. I don't like assignment operation in test just to set things up, I'd prefer an explicit stub. Interestingly, stubbing like this won'twork:

我知道它类似于正确答案,但请耐心等待。我不喜欢测试中的赋值操作只是为了设置,我更喜欢显式存根。有趣的是,磕碰这样将无法正常工作:

allow(request).to receive(:host).and_return("user.myapp.com")

I personally prefer stubbing over assignment, that way I get 2 benefit, one is that it will be validated by rspec's verify double, second is that it is explicitly saying that is a stub, not part of the test excercise.

我个人更喜欢存根而不是赋值,这样我得到了两个好处,一个是它会被rspec 的 verify double 验证,第二个是它明确地说这是一个存根,而不是测试练习的一部分。

回答by sawa

None of the ways suggested in other answers at the point worked for me. This worked:

当时其他答案中建议的任何方法都不适合我。这有效:

Capybara.configure { |config| config.default_host = "my.domain.com" }