I have a hard time testing my controller with before_filters, exceptions and some mocking and stubing.
Here is the controller:
before_filter :get_subject, :only => [:show, :edit, :update, :destroy, :update_field]
before_filter :user_has_to_belongs_to_subject_company, :only => [:show, :edit, :update, :destroy, :update_field]
def show
@messages = @subject.get_user_messages(current_user)
end
private
def get_subject
@subject = Subject.find(params[:id])
end
def user_has_to_belongs_to_subject_company
unless @current_user.company.eql?(@subject.company)
raise "Error: current_user does not belongs to subject's company"
end
end
And here is my spec file:
require 'spec_helper'
describe SubjectsController do
describe "for signed users" do
before(:each) do
@current_user = Factory(:user)
sign_in @current_user
end
describe "for user belonging to subject's company" do
before(:each) do
@subject = mock_model(Subject)
Subject.stub!(:find).with(@subject).and_return(@subject)
@current_user.stub_chain(:company, :eql?).and_return(true)
@subject.stub!(:company)
end
it "should not raise an exception" do
expect { get :show, :id => @subject }.to_not raise_error
end
end
describe "for user not belonging to subject's company" do
before(:each) do
@subject = mock_model(Subject)
Subject.stub!(:find).with(@subject).and_return(@subject)
@current_user.stub_chain(:company, :eql?).and_return(false)
@subject.stub!(:company)
end
it "should raise an exception" do
expect { get :show, :id => @subject }.to raise_error
end
end
end
end
And finally, here is the error message:
SubjectsController for signed users for user belonging to subject's company should not raise an exception
Failure/Error: expect { get :show, :id => @subject }.to_not raise_error
expected no Exception, got #<RuntimeError: Error: current_user does not belongs to subject's company>
# ./spec/controllers/subjects_controller_spec.rb:19:in `block (4 levels) in <top (required)>'
Thx for helping!
I’m not seeing the problem, but here’s a refactoring suggestion. If you find yourself using more mocks and stubs that usual, maybe it’s time to reconsider your interfaces. In this case, you can make your controller skinnier and you model fatter.