【问题标题】:Rails rspec set subdomainRails rspec 设置子域
【发布时间】:2010-03-31 21:32:35
【问题描述】:

我正在使用 rSpec 来测试我的应用程序。在我的应用程序控制器中,我有一个这样的方法:

def set_current_account
  @current_account ||= Account.find_by_subdomain(request.subdomains.first)
end

是否可以在我的规范中设置 request.subdomain ?也许在前块?我是 rSpec 的新手,所以任何关于这方面的建议都会非常感谢。

伊夫

【问题讨论】:

    标签: ruby-on-rails rspec subdomain specifications


    【解决方案1】:

    我想出了如何解决这个问题。

    在我的规范中的前块中,我只是添加了:

    before(:each) do
      @request.host = "#{mock_subdomain}.example.com"
    end
    

    这会将 request.subdomains.first 设置为 mock_subdomain 的值。

    希望有人觉得这很有用,因为它在网上其他任何地方都没有很好地解释。

    【讨论】:

    • 一个小技巧 - 请求既可以作为方法使用,也可以作为实例变量使用。最好通过该方法访问它,以在您和底层 RSpec 代码之间保持一点距离。
    • @lulalala request.host = "#{mock_subdomain}.example.com"
    • 这不适用于我。我还将我的子域 api 添加到 /etc/hosts 中:api.example.com,但我仍然收到无路由错误。有什么想法吗?
    • 我也在 Rails 3 上运行。
    • 确保你不要做'request.host'。它必须是实例变量“@request.host”才能正常工作。
    【解决方案2】:

    我知道这是一个相对较旧的问题,但我发现这取决于您运行的测试类型。我也在运行 Rails 4 和 RSpec 3.2,所以我确信自从提出这个问题以来,有些事情已经发生了变化。

    请求规格

    before { host! "#{mock_subdomain}.example.com" }
    

    Capybara 的功能规格

    before { Capybara.default_host = "http://#{mock_subdomain}.example.com" }
    after  { Capybara.default_host = "http://www.example.com" }
    

    我通常在spec/support 中创建看起来像这样的模块:

    # spec/support/feature_subdomain_helpers.rb
    module FeatureSubdomainHelpers
      # Sets Capybara to use a given subdomain.
      def within_subdomain(subdomain)
        before { Capybara.default_host = "http://#{subdomain}.example.com" }
        after  { Capybara.default_host = "http://www.example.com" }
        yield
      end
    end
    
    # spec/support/request_subdomain_helpers.rb
    module RequestSubdomainHelpers
      # Sets host to use a given subdomain.
      def within_subdomain(subdomain)
        before { host! "#{subdomain}.example.com" }
        after  { host! "www.example.com" }
        yield
      end
    end
    

    包含在spec/rails_helper.rb

    RSpec.configure do |config|
      # ...
    
      # Extensions
      config.extend FeatureSubdomainHelpers, type: :feature
      config.extend RequestSubdomainHelpers, type: :request
    end
    

    然后你可以像这样在你的规范中调用:

    feature 'Admin signs in' do
      given!(:admin) { FactoryGirl.create(:user, :admin) }
    
      within_subdomain :admin do
        scenario 'with valid credentials' do
          # ...
        end
    
        scenario 'with invalid password' do
          # ...
        end
      end
    end
    

    【讨论】:

      【解决方案3】:

      在 Rails 3 中,我尝试手动设置主机的所有操作均无效,但查看代码我注意到它们很好地解析了您传递给请求助手(如 get)的路径。 如果你的控制器去获取子域中提到的用户并将其存储为@king_of_the_castle

      it "fetches the user of the subomain" do
        get "http://#{mock_subdomain}.example.com/rest_of_the_path"
        assigns[:king_of_the_castle].should eql(User.find_by_name mock_subdomain)
      end
      

      【讨论】:

      • 无论这是否是在 Rails 3 中执行此操作的官方方式,将主机直接添加到路径中,正如 ilpoldo 演示的那样对我有用。
      • 这在控制器规格中不起作用。你不能做get "path"。它将解释为动作。出于某种原因,您必须使用get :action_name
      • 是的,上面那个是来自请求规范的 sn-p。
      • 在控制器中,我可能会尝试使用路由器将子域作为参数传递给控制器​​,然后在控制器规范中使用 get :index, :user='ilpoldo' 之类的东西。我不确定它是否有帮助,但我手头有这个例子:gist.github.com/ilpoldo/6052044
      【解决方案4】:
      • Rspec - 3.6.0
      • 水豚 - 2.15.1

      Chris Peters 的回答适用于请求规范,但对于功能规范,我必须进行以下更改:

      rails_helper:

      Capybara.app_host = 'http://lvh.me'
      Capybara.always_include_port = true
      

      feature_subdomain_helpers:

      module FeatureSubdomainHelpers
          def within_subdomain(subdomain)
              before { Capybara.app_host = "http://#{subdomain}.lvh.me" }
              after  { Capybara.app_host = "http://lvh.me" }
              yield
          end
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多