Hi, I''m new to mocha and stubba but eager to learn. I have a rails functional test in which I would like to stub an instance method of particular class to always return true. I tried the following: def test_post_checkout Order.any_instance.stubs(:successful?).returns(true) post :checkout assert_response :redirect assert_equal "Checkout was successful.", flash[:notice] end I expected that the stub would help my test pass but instead it failed and the failure included the following: test/functional/store_controller_test.rb:103:in `test_post_checkout'']: #<Mocha::Mock: 28754118>.successful?() - expected calls: 0, actual calls: 1 I was confused by this and it seemed to indicate that I need to tell Order that a call to #successful? was expected. Do I have to create a mock in order to stub? How do I do this? Thanks, Tim Case tim at karmacrash.com
Hi, I''m new to mocha and stubba but eager to learn. I have a rails functional test in which I would like to stub an instance method of particular class to always return true. I tried the following: def test_post_checkout Order.any_instance.stubs(:successful?).returns(true) post :checkout assert_response :redirect assert_equal "Checkout was successful.", flash[:notice] end I expected that the stub would help my test pass but instead it failed and the failure included the following: test/functional/store_controller_test.rb:103:in `test_post_checkout'']: #<Mocha::Mock: 28754118>.successful?() - expected calls: 0, actual calls: 1 I was confused by this and it seemed to indicate that I need to tell Order that a call to #successful? was expected. Do I have to create a mock in order to stub? How do I do this? Thanks, Tim Case tim at karmacrash.com
On 13/10/06, Tim Case <gk at karmacrash.com> wrote:> > Hi, I''m new to mocha and stubba but eager to learn. I have a rails > functional test in which I would like to stub an instance method of > particular class to always return true. I tried the following: > > def test_post_checkout > Order.any_instance.stubs(:successful?).returns(true) > post :checkout > assert_response :redirect > assert_equal "Checkout was successful.", flash[:notice] > end > > I expected that the stub would help my test pass but instead it failed > and the failure included the following: > > test/functional/store_controller_test.rb:103:in > `test_post_checkout'']: > #<Mocha::Mock: 28754118>.successful?() - expected calls: 0, actual calls: > 1 > > I was confused by this and it seemed to indicate that I need to tell > Order that a call to #successful? was expected. Do I have to create a > mock in order to stub? How do I do this? > > Thanks, > > Tim Case > tim at karmacrash.com >Hi Tim, A first glance your test looks fine and it sounds like you understand how it should work. Can you send the code for your checkout action? Also can you tell me whether you are using the gem (which version?) or the Rails plugin (which revision?) - I''ve been making a few fairly big changes in HEAD recently and I may have inadvertantly introduced a bug to the Rails plugin. -- James. http://blog.floehopper.org -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/mocha-developer/attachments/20061013/893476e0/attachment.html
James Mead wrote:> On 13/10/06, *Tim Case* <gk at karmacrash.com <mailto:gk at karmacrash.com>> > wrote: > > Hi, I''m new to mocha and stubba but eager to learn. I have a rails > functional test in which I would like to stub an instance method of > particular class to always return true. I tried the following: > > def test_post_checkout > Order.any_instance.stubs(:successful?).returns(true) > post :checkout > assert_response :redirect > assert_equal "Checkout was successful.", flash[:notice] > end > > I expected that the stub would help my test pass but instead it > failed > and the failure included the following: > > test/functional/store_controller_test.rb:103:in > `test_post_checkout'']: > #<Mocha::Mock: 28754118>.successful?() - expected calls: 0, actual > calls: 1 > > I was confused by this and it seemed to indicate that I need to tell > Order that a call to #successful? was expected. Do I have to create a > mock in order to stub? How do I do this? > > Thanks, > > Tim Case > tim at karmacrash.com <mailto:tim at karmacrash.com> > > > Hi Tim, > > A first glance your test looks fine and it sounds like you understand > how it should work. Can you send the code for your checkout action? > Also can you tell me whether you are using the gem (which version?) or > the Rails plugin (which revision?) - I''ve been making a few fairly big > changes in HEAD recently and I may have inadvertantly introduced a bug > to the Rails plugin. > -- > James. > http://blog.floehopper.org > ------------------------------------------------------------------------ > > _______________________________________________ > mocha-developer mailing list > mocha-developer at rubyforge.org > http://rubyforge.org/mailman/listinfo/mocha-developerHi James, thanks for your help I installed mocha as a rails plugin from revision 70. the checkout action calls process order: def checkout @order = Order.new_order(@store.bill_type.name, params[:order]) @customer = find_or_create_customer @order.store = @store @line_items = @cart.line_items @order.line_items << @cart.line_items if @order.valid? and @customer.valid? process_order else append_to_order_errors @customer.errors render_errors_in_order_summary end end def process_order if @order.process and @order.successful? #<---This is what I want to stub @cart.empty! if customer_logged_in? flash[:notice] = "Checkout was successful." else flash[:notice] = "Checkout was successful, and your account was created." end redirect_to_order_confirmation @order.id return else render_errors_in_order_summary end end @order.successful? is what I would like to return a true when I specify it and at times false when I specify it.
On 13/10/06, Tim Case <gk at karmacrash.com> wrote:> > Hi James, thanks for your help I installed mocha as a rails plugin from > revision 70. > > the checkout action calls process order: > > > def checkout > @order = Order.new_order(@store.bill_type.name, params[:order]) > @customer = find_or_create_customer > @order.store = @store > @line_items = @cart.line_items > @order.line_items << @cart.line_items > if @order.valid? and @customer.valid? > process_order > else > append_to_order_errors @customer.errors > render_errors_in_order_summary > end > end > > def process_order > if @order.process and @order.successful? #<---This is what I want > to stub > @cart.empty! > if customer_logged_in? > flash[:notice] = "Checkout was successful." > else > flash[:notice] = "Checkout was successful, and your account was > created." > end > redirect_to_order_confirmation @order.id > return > else > render_errors_in_order_summary > end > end > > @order.successful? is what I would like to return a true when I specify > it and at times false when I specify it. >Hi Tim, I still can''t see anything obviously wrong - although my brain is in Friday afternoon mode. I''ve created a new Rails project and installed the same version of the plugin as you and I''ve tried some simple tests to try and replicate what you''re seeing, but with no luck. I''m using version Rails 1.0.0 - what version are you using? @order should be a real Order unless you are doing some other mocking out in a setup() method. Do you have any other setup code? The error you are seeing implies that @order is a mock object and not a real object - it is saying that there has been an unexpected call to the successful? method. You can generate the same error by doing something like this... def test_me order = mock() order.successful? end But it should not be possible to get the same error on a real object. I suggest you add the following line at the top of the process_order() method... p @order An then we can see whether its a mock or a real object. The only other thing I can think of is that Mocha might not be clearing up correctly after itself between tests. Do you get the same error if you comment out all the other test methods in that TestCase? -- James. http://blog.floehopper.org -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/mocha-developer/attachments/20061013/93898494/attachment.html
Hi Tim,> > I still can''t see anything obviously wrong - although my brain is in > Friday afternoon mode. I''ve created a new Rails project and installed > the same version of the plugin as you and I''ve tried some simple tests > to try and replicate what you''re seeing, but with no luck. I''m using > version Rails 1.0.0 - what version are you using? > > @order should be a real Order unless you are doing some other mocking > out in a setup() method. Do you have any other setup code? The error > you are seeing implies that @order is a mock object and not a real > object - it is saying that there has been an unexpected call to the > successful? method. You can generate the same error by doing something > like this... > > def test_me > order = mock() > order.successful? > end > > But it should not be possible to get the same error on a real object. > > I suggest you add the following line at the top of the process_order() > method... > > p @order > > An then we can see whether its a mock or a real object. > > The only other thing I can think of is that Mocha might not be > clearing up correctly after itself between tests. Do you get the same > error if you comment out all the other test methods in that TestCase? > -- > James. > http://blog.floehopper.org > ------------------------------------------------------------------------ > > _______________________________________________ > mocha-developer mailing list > mocha-developer at rubyforge.org > http://rubyforge.org/mailman/listinfo/mocha-developerJames, just figured it out and everything works! Here''s what was going on: class Order < ActiveRecord::Base def successful? end end class CcOrder < Order end def test_post_checkout Order.any_instance.stubs(:successful?).returns(true) post :checkout assert_response :redirect assert_equal "Checkout was successful.", flash[:notice] end CcOrder is the concrete class that was actually getting called in the process_order method inside the store controller code. In the test, I was stubbing out the method from CcOrder''s parent class Order, by changing the stub to operate on CcOrder the test worked as expected. def process_order if @order.process and @order.successful? /*<-- at order is a CcOrder not Order*/ @cart.empty! if customer_logged_in? flash[:notice] = "Checkout was successful." else flash[:notice] = "Checkout was successful, and your account was created." end redirect_to_order_confirmation @order.id return else render_errors_in_order_summary end end def test_post_checkout CcOrder.any_instance.stubs(:successful?).returns(true) post :checkout assert_response :redirect assert_equal "Checkout was successful.", flash[:notice] end It seems to me that the original call to stub Order should have propagated down to Order''s child classes as well. Is this by design or something for the future? (Maybe I can help) A new mocha fan! Nice work James!!! Tim Case tim at karmacrash.com
On 13/10/06, Tim Case <gk at karmacrash.com> wrote:> > James, just figured it out and everything works! Here''s what was going > on: > > class Order < ActiveRecord::Base > def successful? > end > end > > class CcOrder < Order > end > > def test_post_checkout > Order.any_instance.stubs(:successful?).returns(true) > post :checkout > assert_response :redirect > assert_equal "Checkout was successful.", flash[:notice] > end > > CcOrder is the concrete class that was actually getting called in the > process_order method inside the store controller code. In the test, I > was stubbing out the method from CcOrder''s parent class Order, by > changing the stub to operate on CcOrder the test worked as expected. > > def process_order > if @order.process and @order.successful? /*<-- at order is a CcOrder > not Order*/ > @cart.empty! > if customer_logged_in? > flash[:notice] = "Checkout was successful." > else > flash[:notice] = "Checkout was successful, and your account was > created." > end > redirect_to_order_confirmation @order.id > return > else > render_errors_in_order_summary > end > end > > def test_post_checkout > CcOrder.any_instance.stubs(:successful?).returns(true) > post :checkout > assert_response :redirect > assert_equal "Checkout was successful.", flash[:notice] > endGreat - I''m glad you worked it out - it all makes sense now. It seems to me that the original call to stub Order should have> propagated down to Order''s child classes as well. Is this by design or > something for the future? (Maybe I can help)It''s not by design - more by accident. We don''t tend to use the any_instance() functionality much, so I guess we just haven''t come across a case like this. Maybe it is something we should support. A new mocha fan! Nice work James!!! Thanks - I''m glad you''re finding it useful. -- James. http://blog.floehopper.org -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/mocha-developer/attachments/20061013/32e262a0/attachment.html