Testing Merb controllers with RSpec
I've been trying out Merb recently, and I'm liking it. However, I've spent a lot of time stumbling around the interweb looking for examples of what I've been trying to achieve. So far I've been coming up short. The Merb API docs are good, but you can't beat a good example.
Just so you know, I'm currently using Merb 0.9.2.
When you create your controller with
merb-gen controller MyController, the generated RSpec file (in the
spec/controllers directory) contains something like this:
describe MyController, "index action" do before(:each) do dispatch_to(MyController, :index) end end
In order to unit test the controller you need to be able to call RSpec's
should method on it. This is well and good, but the API docs don't make it particuarly obvious how you get hold of the controller itself.
There's obviously going to be a common idiom for setting this up. Could Google find it? Nope. But IRC could.
do_request returns a controller, so you can modify the
before block ever so slightly:
describe MyController, "index action" do before(:each) do @controller = do_request(MyController, :index) end it "should render successfully" do @controller.should render_successfully end end
As the Merb docs point out, because
do_request bypasses the router it's ideally suited for unit testing a controller. You choose the method, you set your expectations, you write your test.
Talking of which, just how do you set expectations on the controller for calls that take place during the
do_request call? The syntax is rather neat; you pass a block, like this:
before(:each) do @controller = do_request(MyController, :index) do |controller| controller.should_receive(:render).with(:new) end end
Update: Almost as soon as I posted this I discovered that there's a great page on the Merb wiki about testing Merb with rspec...
I love feedback and questions — please get in touch on Twitter or leave a comment.