Question

How to emulate the following behaviour using RhinoMocks?

The tested method invokes ReceivePayment method on an interface.

public void TestedMethod(){
    bool result = interface.ReceivePayment();        
}

Interface has the CashAccepted event. ReceivePayment shoud return true if this event has been invoked several times (or by a condition).

How to accomplish such a task?

update.

Now I do the following:

UpayError error;
        paymentSysProvider.Stub(i => i.ReceivePayment(ticketPrice,
            App.Config.SellingMode.MaxOverpayment, uint.MaxValue, out error))
            .Do( new ReceivePaymentDel(ReceivePayment));

        paymentSysProvider.Stub(x => x.GetPayedSum()).Return(ticketPrice);

        session.StartCashReceiving(ticketPrice);

        paymentSysProvider.Raise(x => x.CashInEvent += null, cashInEventArgs);

public delegate bool ReceivePaymentDel(uint quantityToReceive, uint maxChange, uint maxTimeout, out UpayError error);
public bool ReceivePayment(uint quantityToReceive, uint maxChange, uint maxTimeout, out UpayError error) {
        Thread.Sleep(5000);
        error = null;
        return true;
    }

StartCashReceiving returns immediately since there is a task launch inside. But the next line: paymentSysProvider.Raise(...) is waiting for the completion of the ReceivePayment stub!

Was it helpful?

Solution

You can use WhenCalled. Actually I didn't understand your question (Is the event fired by the mock or by the unit under test? Who is handling the event?)

There is some sample code:

bool fired = false;

// set a boolean when the event is fired.
eventHandler.Stub(x => x.Invoke(args)).WhenCalled(call => fired = true);

// dynamically return whether the eventhad been fired before.
mock
  .Stub(x => x.ReceivePayment())
  .WhenCalled(call => call.ReturnValue = fired)
  // make rhino validation happy, the value is overwritten by WhenCalled
  .Return(false);

When you trigger the event in your test, you could also reconfigure the mock after firing:

mock
  .Stub(x => x.ReceivePayment())
  .Return(false);

paymentSysProvider.Raise(x => x.CashInEvent += null, cashInEventArgs);

mock
  .Stub(x => x.ReceivePayment())
  .Return(true)
  .Repeat.Any(); // override previous return value.

OTHER TIPS

Are you testing ReceivePayment? If not, you really should not be worried about how that interface is implemented (see http://blinkingcaret.wordpress.com/2012/11/20/interaction-testing-fakes-mocks-and-stubs/).

If you must, you can use the .Do extension method, for example:

interface.Stub(i => i.ReceivePayment()).Do((Func<bool>) (() => if ... return true/false;));

See: http://ayende.com/blog/3397/rhino-mocks-3-5-a-feature-to-be-proud-of-seamless-do http://weblogs.asp.net/psteele/archive/2011/02/02/using-lambdas-for-return-values-in-rhino-mocks.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top