[mocha-developer] If I stub do I have to mock as well?

Tim Case gk at karmacrash.com
Fri Oct 13 16:04:20 EDT 2006


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-developer
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]
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



More information about the mocha-developer mailing list