Reputation: 7466
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?
Upvotes: 3
Views: 429
Reputation: 81
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
Upvotes: 1