TIL: Testing actions in Hanami 2
I was pairing with a colleague this afternoon at work on trying to test an action in Hanami 2 where we explicitly needed to read the body of the request.
The action looked something like this:
class MyAction < Action
before_action :some_validation
def handle(req, res)
event_id = req.params[:event_id]
ticket_id = req.params[:ticket_id]
# do things with params here
end
private
def some_validation(req, res)
body = req.body.read
request_url = "..."
# compare the SHA of body + some other things against a header in the request
end
end
Generally, the approach I would take for testing an action like this is to create a new instance of the action, and then call it with some params.
let(:subject) { MyAction.new }
it "works" do
subject.call({event_id: "123", ticket_id: "246"})
end
However, that doesn't exactly work when trying to read the body off the request.
When calling req.body.read, we get no method read error for nil.
To get that to work, we need to call the action with an object that loosely resembles the env object of a Rack request, specifically an object with a rack.input key. This is what Rack uses to build the request body.
For example:
params = StringIO.new(JSON.generate({event_id: "123", ticket_id: "246"}))
subject.call({"rack.input" => params})
Success! req.body.read is now accessible in our action under test!