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
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. :)
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..
It isn't.
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..
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?
The problem is that this is not valid syntax. How do I get this to work?
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.
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);
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", ...);
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.
Comment preview