Ayende @ Rahien

Unnatural acts on source code

Natural Event Syntax for Rhino Mocks

 

I asked before, but didn't get any conclusive answers, what do you think about this syntax for raising events in Rhino Mocks. I spiked the implementation, and the code blow works. As I said, I don't like the awkward syntax of GetLastEventRaiser(), nor the reliance on EventRaiser.Create(mock, "Load"), because it relies on strings.

Does it make sense? Readable? Maintainable?

[Test]
public void Raise_FromEventRaiser_RaiseTheEvent()
{
    MockRepository mocks = new MockRepository();
    IWithCustomEvents withCustomEvents = mocks.DynamicMock<IWithCustomEvents>();
    mocks.ReplayAll();
    
    bool myEventCalled = false;
    withCustomEvents.MyEvent += delegate { myEventCalled = true; };

    withCustomEvents.MyEvent += EventRaiser.Raise(this, EventArgs.Empty);

    Assert.IsTrue(myEventCalled);
}

I wanted to say that the implementation was simple, but it relies on emitting code at runtime, so is it simple?

Anyway, I am waiting for some additional responses

Comments

Ha
06/23/2007 04:45 PM by
Ha

This is definitely a tricky problem to solve. I think this syntax works. It'd be nice to be able to setup an expectation for the event being raised rather than having to attach the event twice, but I think what you have here works for me. :)

Diego
06/23/2007 06:21 PM by
Diego

It´s great, but it will be prittier to me you write something like this:

EventRaiser.Raise(withCustomEvents.MyEvent);

Of couse, I don´t know if this way is posible..

Roy Osherove
06/23/2007 07:42 PM by
Roy Osherove

the intent is very unclear and you have to be extra careful to make sure you "get" the fact that an event is actually being thrown..

Simone Chiaretta
06/23/2007 10:29 PM by
Simone Chiaretta

I don't like that you have to register an event handler for the event in order to force the mockObject to raise that event.

It would have been great if it were possible to say EventRaiser.Raise(myEvent, myEventArgs), but you already said it's not.

And what about

EventRaiser.Create(mock, myEvent, myEventArgs)? is this possible?

Ayende Rahien
06/23/2007 11:49 PM by
Ayende Rahien

The problem is that this is not valid syntax. How do I get this to work?

Thomas Eyde
06/24/2007 12:01 AM by
Thomas Eyde

I find it confusing that adding an event handler also will raise the event. We really wish that object members were real, first class objects, don't we?

How about:

withCustomEvents.MyEvent += delegate { myEventCalled = true; };

withCustomEvents.MyEvent += EventRaiser.Create(out handler);

handler.RaiseEvent();

Assert.IsTrue(myEventCalled);

I left out the default parameters to the event handler, as I usually don't need them.

Simone
06/24/2007 12:45 AM by
Simone

I never tried using rhino mock with an event till now, I don’t know how it works now…

Don’t know if it’s feasible or not, but adding an event handler to the event you want to raise seems a bit confusing to me…

I know this uses strings:

IEventRaiser loadRaiser = new EventRaiser((IMockedObject)mockedView, "Load");

But in my opinion expresses better the intent that you want the mockedView to raise the Load event then writing

mockedView.Load += EventRaiser.Raise(this, EventArgs.Empty);

Jeff Brown
06/24/2007 01:23 AM by
Jeff Brown

I think this is pretty terrible and unintuitive syntax. It looks like the EventRaiser is being attached to the event. Of course it isn't.

What's wrong with something like this:

mockedView.Load += null; // don't actually add a handler

EventRaiser eventRaiser = LastCall.GetEventRaiser(); // but do get the raiser for it.

eventRaiser.Raise(...);

Or the shorthand:

mockedView.Load += null;

LastCall.RaiseEvent(...);

If it comes to it, I don't really mind the string version. At least its intent is clear and free of side-effects.

Mocks.RaiseEvent(mockedView, "Load", ...);

MHolmgren
06/25/2007 07:47 AM by
MHolmgren

Any string syntax = The Horror! (use "some other" mocking framework)

Any code that looks like it is not raising an event when it is = No

Sorry for being a PIA, but readability is really high on my list.

Comments have been closed on this topic.