使用rspec和存根的故障测试控制器
我很难用before_filters,异常和一些模拟和存根测试我的控制器。 这里是控制器:使用rspec和存根的故障测试控制器
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
这里是我的规格文件:
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
最后,这里是错误消息:
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的帮助!
我没有看到问题,但这里有一个重构建议。如果你发现自己使用了更多的模拟和存根,那么也许是时候重新考虑你的接口了。在这种情况下,你可以让你的控制器变得更瘦,而且你的模型更加健壮。
# subjects_controller_spec.rb
describe "for user belonging to subject's company" do
before(:each) do
@subject = mock_model(Subject, :verify_user => true)
Subject.stub!(:find).with(@subject).and_return(@subject)
end
# subjects_controller.b
def user_has_to_belongs_to_subject_company
@subject.verify_user(@current_user)
end
# subject.rb
class Subject
def verify_user(user)
unless user.company.eql?(company)
raise "Error: current_user does not belongs to subject's company"
end
Thx它有很大的帮助。 – 2011-06-17 14:20:44
,如果你删除在@current_user前面的@
def user_has_to_belongs_to_subject_company
unless @current_user.company.eql?(@subject.company)
得到
def user_has_to_belongs_to_subject_company
unless current_user.company.eql?(@subject.company)
而在你的规格,也controller.stub会发生什么!(:CURRENT_USER).and_return @ current_user
我认为问题是范围之一 - 您的测试中的@current_user与控制器中的@current_user不同。真的取决于如何实现“sign_in @current_user”。
此外,而不是引发异常,也许你的before_filter可以重定向用户到另一个页面并设置flash [:错误]?之前的过滤器是处理这种情况的正确的地方,所以它不应该引发必须在其他地方拯救的异常(或者如果没有,它会向用户显示500页)。
Thx太,我遵循你的建议,只是做了闪光[:错误]和重定向:) – 2011-06-17 14:21:09
删除我的答案,因为我在阅读时错过了一些代码。 – jaydel 2011-06-17 12:41:18