Rack apps are generally straightforward to test because of their very basic public interface. But where do we put specific things, in this case, a cookie for the request, on that
env argument it takes? Here’s one way.
env argument that is sent to
#call in a Rack app is an variable that represents the environment of the request. It is a hash of CGI-like headers: request method, query params, http headers – that sort of thing.
HTTP_* keys on the hash will be read as request headers from the environment.
Rack MockRequest Cookies
Rack provides a great little
Rack::MockRequest helper object in its library that will help us test our app. This object has a class method called
env_for which allows for quick construction of an
env var that is a request to a specified url.
On the returned
env we will continue to make modifications before passing it to our Rack app. We’ll add our cookie header with a key of
HTTP_COOKIE. The value will be of the format
cookieName=cookieValue. We can handle multiple cookies by separating the cookies with
Let’s say we’re testing a token authentication middleware with rspec. Our spec may look something like this:
it "accepts an cookie token in the request" do middleware = # ... instantiate rack middleware env = Rack::MockRequest.env_for("/protected") env["HTTP_COOKIE"] = "AUTH_COOKIE=123" status, _, _ = middleware.call(env) expect(status).to eq(200) end
Then in our Rack app source, we can code for the availability of a cookie on the request. It might look like:
# ... def call(env) request = Rack::Request.new(env) token = request.cookies["AUTH_TOKEN"] # ... end
Is this the easiest or best way to set cookies on requests when testing Rack apps? What do you do?