[mocha-developer] counter-intuitive behaveour when passing a proc to Mocha::Expectation#returns

Tomas Pospisek tpo2 at sourcepole.ch
Thu Jan 11 11:39:55 EST 2007


Quoting Chris Roos <chrisjroos at gmail.com>:

> <snip>
> >
> > The example given for a stub in the referred essay is this:
> >
> >   public class MailServiceStub implements MailService {
> >     private List<Message> messages = new ArrayList<Message>();
> >     public void send (Message msg) {
> >       messages.add(msg);
> >     }
> >     public int numberSent() {
> >       return messages.size();
> >     }
> >   }
> >
> > Mocha won't allow you to do this, since you'd need to have access to
> "Message
> > msg" when stubbing the "send" method above, which isn't the case as you
> note.
>
> Maybe not, but ruby will :-)  The equivalent would be, as James
> previously suggested, a fake version.  Somewhere in the load path of
> your tests, you would define the above class.  Something like:
>
> class MailServiceStub
>   def initialize(messages = [])
>     @messages = messages
>   end
>   def send(msg)
>     @messages.add(msg)
>   end
>   def number_sent
>     @messages.size
>   end
> end

Yup, that's how I was previously doing it, i.e. all mocking/stubbing/faking etc
programmed by hand. However, since I don't much use (or like - it makes me not
understand my own code any more after a while) dependency injection, and the
method I want to stub ahhhhhh aka mock is instantiated somewhere deep inside my
class/object hierarchy, I had to sneak through all those layers to define it
there. Which was very ugly and error prone, since I would forget to redefine my
"stubbed" method back to its original in some test, making another completely
unrelated test way down the chain fail for no trivially apparent reason.

That's why I much, much prefer using Mocha. It makes my life *way* easier, since
it's cleanly and properly done... :-)))

> > Thus we are not able to save the message for further verification - f.ex.
> if the
> > calling unit, which we want to test is actually passing the message on to
> the
> > MailServiceStub or whether it's eating it.
> >
> Actually, you don't need the MailServiceStub in order to test whether
> your calling unit is passing the message on.  You would probably have
> something like:
>
> def test_should_pass_message_to_mail_service
>   message = stub
>   mail_service = mock
>   mail_service.expects(:send).with(message)
>   client = Client.new
>   client.send_message(mail_service, message)
> end
>
> A simple Client to satisfy this test would be:
>
> class Client
>   def send_message(mail_service, message)
>     mail_service.send(message)
>   end
> end
>
> To be honest, I'm slightly confused by your two messages but am hoping
> this explanation helps a bit.

It's actually how I finally did it - by using with...

Thanks,
*t

----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.


More information about the mocha-developer mailing list