Hello, I''m trying learn Rspec but having problems to understand when and how user mocks and stubs. I have a properties_controller with to before_filter actions (check_administrator_role e load_user)... to access index action of properties_controller I need have a params[:user] and this parameter will be used to load ther user in method load_user ... Like bellow: before_filter :check_administrator_role before_filter :load_user # GET /properties def index @properties = @user.properties end private def load_user @user = User.find(params[:user_id]) if @user.nil? flash[:notice] = "Registro não encontrado" redirect_to root_path end end But I don''t know how test index and load_user without fixtures, take a look on my specs: describe PropertiesController do def mock_property(stubs={}) @mock_property ||= mock_model(Property, stubs) end before do @current_user = mock_model(User, :id => 1) controller.stub!(:check_administrator_role).and_return(true) @user = mock_model(User, :id=>1) controller.stub!(:load_user).and_return(@user) end describe "responding to GET index" do it "should expose all properties of given user as @properties" do @user.should_receive(:properties).and_return([mock_property]) get :index assigns[:properties].should == [mock_property] end end But I having this error: NoMethodError in ''PropertiesController responding to GET index should expose all properties of given user as @properties'' You have a nil object when you didn''t expect it! The error occurred while evaluating nil.properties /Users/daniellopes/Trabalhos/luvima/luvima/app/controllers/properties_controller.rb:8:in `index'' ./spec/controllers/properties_controller_spec.rb:21: So, how is the right way to mock associated records? Thanks. Atenciosamente, Daniel Lopes ? Area Cria??es Design, Websites e Sistemas Web Visite: http://www.areacriacoes.com.br/projects http://blog.areacriacoes.com.br/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 55 (31) 3077-4560 / 55 (31) 8808-8748 / 55 (31) 8737-7501 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081205/b82f857b/attachment-0001.html>
On 5 Dec 2008, at 13:42, Daniel Lopes wrote:> NoMethodError in ''PropertiesController responding to GET index > should expose all properties of given user as @properties'' > You have a nil object when you didn''t expect it! > The error occurred while evaluating nil.properties > /Users/daniellopes/Trabalhos/luvima/luvima/app/controllers/ > properties_controller.rb:8:in `index'' > ./spec/controllers/properties_controller_spec.rb:21: > > So, how is the right way to mock associated records?Hi Daniel The error you are seeing is because the assignment to @user happens inside #load_user: the live code never call` `@user = load_user`. As far as possible, you want to avoid modifying objects under test - private methods are only the business of instances of that class. It''s much safer in this case to do User.should_receive(:find).and_return(@user) That way, the filter will run as normal. As for the association - it''s actually irrelevant what that returns. All you care is that whatever comes out of `@user.properties` is assingned to the view. I tend to use symbols to represent objects (including arrays) that get passed around. For example: describe PropertiesController do # Not needed # def mock_property(stubs={}) # @mock_property ||= mock_model(Property, stubs) # end before do controller.stub!(:check_administrator_role).and_return(true) @user = mock_model(User, :id=>1, :properties => :user_properties) User.stub!(:find).and_return(@user) end describe "responding to GET index" do it "should expose all properties of given user as @properties" do get :index assigns[:properties].should == :user_properties end end end HTH Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
Daniel Area Criações
2008-Dec-05 20:26 UTC
[rspec-users] problem to mock association proxy
Thanks Ashley, now the tests passed... but I want understand one thing: This line is only saying that @properties (assigned[:properties]) have some value ... is that? assigns[:properties].should == :user_properties I can change above to assigns[:properties].should_not be_nill and the semantic value will be the same, right? Thanks... Atenciosamente, Daniel Lopes ? Area Cria??es Design, Websites e Sistemas Web Visite: http://www.areacriacoes.com.br/projects http://blog.areacriacoes.com.br/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 55 (31) 3077-4560 / 55 (31) 8808-8748 / 55 (31) 8737-7501 On Fri, Dec 5, 2008 at 6:16 PM, Ashley Moran <ashley.moran at patchspace.co.uk>wrote:> > On 5 Dec 2008, at 13:42, Daniel Lopes wrote: > > NoMethodError in ''PropertiesController responding to GET index should >> expose all properties of given user as @properties'' >> You have a nil object when you didn''t expect it! >> The error occurred while evaluating nil.properties >> /Users/daniellopes/Trabalhos/luvima/luvima/app/controllers/properties_controller.rb:8:in >> `index'' >> ./spec/controllers/properties_controller_spec.rb:21: >> >> So, how is the right way to mock associated records? >> > > Hi Daniel > > The error you are seeing is because the assignment to @user happens inside > #load_user: the live code never call` `@user = load_user`. As far as > possible, you want to avoid modifying objects under test - private methods > are only the business of instances of that class. It''s much safer in this > case to do > > User.should_receive(:find).and_return(@user) > > That way, the filter will run as normal. > > As for the association - it''s actually irrelevant what that returns. All > you care is that whatever comes out of `@user.properties` is assingned to > the view. I tend to use symbols to represent objects (including arrays) > that get passed around. For example: > > describe PropertiesController do > > # Not needed > # def mock_property(stubs={}) > # @mock_property ||= mock_model(Property, stubs) > # end > > before do > controller.stub!(:check_administrator_role).and_return(true) > @user = mock_model(User, :id=>1, :properties => :user_properties) > User.stub!(:find).and_return(@user) > end > > describe "responding to GET index" do > it "should expose all properties of given user as @properties" do > get :index > assigns[:properties].should == :user_properties > end > end > > end > > HTH > > Ashley > > -- > http://www.patchspace.co.uk/ > http://aviewfromafar.net/ > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081205/14f64e67/attachment.html>
On 5 Dec 2008, at 20:26, Daniel Area Cria??es wrote:> This line is only saying that @properties (assigned[:properties]) > have some value ... is that? > assigns[:properties].should == :user_properties > > I can change above to assigns[:properties].should_not be_nill and > the semantic value will be the same, right?Ah no, the semantic value is different because this would also pass: def index @properties = "vegetable soup" end Yet that does not implement the same behaviour. When you write a behaviour example, always ask the question "What could I realistically write that could pass this but not give the desired behaviour?" That way you will avoid false confidence in specs where the behaviour could be broken in the future (perhaps during refactoring), but RSpec still reports success. Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/
Daniel Area Criações
2008-Dec-05 20:51 UTC
[rspec-users] problem to mock association proxy
Thanks Ashley, you right. Atenciosamente, Daniel Lopes ? Area Cria??es Design, Websites e Sistemas Web Visite: http://www.areacriacoes.com.br/projects http://blog.areacriacoes.com.br/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 55 (31) 3077-4560 / 55 (31) 8808-8748 / 55 (31) 8737-7501 On Fri, Dec 5, 2008 at 6:41 PM, Ashley Moran <ashley.moran at patchspace.co.uk>wrote:> > On 5 Dec 2008, at 20:26, Daniel Area Cria??es wrote: > > This line is only saying that @properties (assigned[:properties]) have >> some value ... is that? >> assigns[:properties].should == :user_properties >> >> I can change above to assigns[:properties].should_not be_nill and the >> semantic value will be the same, right? >> > > > Ah no, the semantic value is different because this would also pass: > > def index > @properties = "vegetable soup" > end > > Yet that does not implement the same behaviour. > > When you write a behaviour example, always ask the question "What could I > realistically write that could pass this but not give the desired > behaviour?" That way you will avoid false confidence in specs where the > behaviour could be broken in the future (perhaps during refactoring), but > RSpec still reports success. > > > Ashley > > -- > http://www.patchspace.co.uk/ > http://aviewfromafar.net/ > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081205/2056a637/attachment.html>