Making Rails tests aware of Rack middleware outside Rails's internal chain

后端 未结 2 1092
旧时难觅i
旧时难觅i 2021-02-02 14:37

Context: an application uses a piece of Rack middleware that must be setup in config.ru, rather than Rails\'s internal Middleware chain. This i

相关标签:
2条回答
  • 2021-02-02 15:30

    I think the problem is that ActionDispatch::IntegrationTest uses your Rails.application as its Rack app for the test.

    So, if you can wrap that Rack::Rewrite rule into some Rack middleware, you should be able to override the Rack app you're testing in your test with:

    ActionDispatch::IntegrationTest.app = MyRewriteMiddleware
    
    0 讨论(0)
  • 2021-02-02 15:35

    (Thanks Dan Croak for setting me on the right track. This answer completes what he said).

    Short answer

    Can't be done for functional tests.

    For integration tests, add the following to your test_helper.rb:

    ActionDispatch::IntegrationTest.app = Rack::Builder.new do
      eval File.read(Rails.root.join('config.ru'))
    end
    

    Long answer

    Functional tests are just unit tests run against controllers. When you say, for example get :index, you are not resolving a route. Instead, this is a shorthand for calling the index method, with a request environment that includes a mention to the HTTP method being GET.

    Therefore, it makes sense that your Rack stack does not influence functional tests.

    Integration tests are a different matter. You are testing your full stack there, so you will want to test your Rack middlewares too. Only problem is that, by default, these tests only see the middlewares that you add using Rails's own API.

    But I say "by default" because Rails offers a way to change what Rack stack will be tested. By default, integration tests call Rails.application for their requests. You can change this to anything that suits your needs.

    By using the code above, we use Rack::Builder create an ad-hoc Rack application. Inside the block, you can put any code that you would normally put inside a config.ru file. To avoid code duplication, eval loads our config.ru file. Now our integration tests will load exactly the same application that our app servers expose.

    0 讨论(0)
提交回复
热议问题