In all my ruby on rails app, I try to not use the database in controllers, since they should be independent from persistence classes. I used mocking instead.
Here is the example for rspec and rspec-mock:
class CouponsController < ApplicationController
def index
@coupons = Coupon.all
end
end
require 'spec_helper'
describe CouponsController do
let(:all_coupons) { mock }
it 'should return all coupons' do
Coupon.should_receive(:all).and_return(all_coupons)
get :index
assigns(:coupons).should == all_coupons
response.should be_success
end
end
But what if controller contains more complex scopes, like:
class CouponsController < ApplicationController
def index
@coupons = Coupon.unredeemed.by_shop(shop).by_country(country)
end
end
Do you know any good approach for testing simillar scopes chains?
I think that the following test does not look really good:
require 'spec_helper'
describe CouponsController do
it 'should return all coupons' do
Coupon.should_receive(:unredeemed).and_return(result = mock)
result.should_receive(:by_shop).with(shop).and_return(result)
result.should_receive(:by_country).with(country).and_return(result)
get :index
assigns(:coupons).should == result
response.should be_success
end
end
You could use stub_chain
method for that.
Something like:
Coupon.stub_chain(:unredeemed, :by_shop, :by_country).and_return(result)
Just an example.