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...