How to enable middlewares in integration tests for a rack-app?

366 Views Asked by At

When writing integration tests for a Rack app, I would like to test the app with all the middlewares that are enabled in runtime environment through classic config.ru file.

Using rack-app, I can instantiate the Rack app with:

describe App do

  include Rack::App::Test
  rack_app described_class

  describe '/hello' do
    get '/example/endpoint/'
    # ...
  end
end

With naked rack, it would look the same:

include Rack::Test::Methods
let(:app) { Application }

But then there are no enabled middlewares since the app is not instantiated through config.ru where use commands enable them.

How to enable the middlewares in tests so that the requests run through them in examples?

1

There are 1 best solutions below

0
On

Is the logic in the middleware is a must requirement of a rack-app class?

If yes, then it should be used directly in the rack-app class, and it should be a simple spec as you would do normally. You define the rack-app subject with the rack_app ClassNameHere and do the testing. The Pro for this approach is that you don't have to know from the spec point of view, that some logic is in middlewares and some located in the controller part, as they are implementation details. As long the expected behavior is fulfilled in the spec test cases, it should be good.

But if the answer is no, then it should be tested independently and there should be one place where all the integrations usually are done. I usually do the composition of sub-rack-apps and middlewares in a top-level rack-app where I only use the use and the mount keywords and create an integration test to ensure routing and confirm the expected behavior of middlewares.

Is the logic in the middleware is a form of contract to the application, like the middleware ensure an value in the rack call env, but the value is not coupled with the middleware, then I would test the middleware on its own. And in the rack-app class spec, I would guarantee the entity in the rack call env. This will support the project's long-term maintenance aspects, and also makes the rack-app class easily reusable.

On the other hand, if you really need to test together but not use the middleware in the class directly then you can use the following idiom in the spec:

rack_app do
  use MiddlewareNameHere, params
  mount AppToTestWithTheMiddleware
end

Cheers, Adam