Alternate syntax for raising events from mocks

58 views
Skip to first unread message

David Tchepak

unread,
Jun 23, 2008, 9:57:00 PM6/23/08
to Rhino.Mocks
Hi all,

I've been playing around with an alternate syntax for raising events
from mocks, based on an event subscription in a delegate (the
mock.Raise(...) call):

[Fact]
public void Suggestion_for_raising_events() {
var mock = MockRepository.GenerateMock<IDoSomething>();
var wasCalled = false;
mock.SomethingDone += (sender, e) => wasCalled = true;

mock.Raise(x => x.SomethingDone += null, mock, EventArgs.Empty);

Assert.True(wasCalled);
}

It reads fairly clearly to me, but I'm fairly new to mocking and Rhino
Mocks so I may have an odd perspective on this. I've implemented it by
abusing existing Rhino Mocks methods (3.5 beta) and .NET 3.5
extensions methods, but am keener on the syntax than the
implementation:

public static class EventRaiserExtensions {
private static IEventRaiser
GetEventRaiserFromSubscription<TEventSource>(
this TEventSource mock, Action<TEventSource>
eventSubscription) {

return mock
.Stub(eventSubscription)
.IgnoreArguments()
.GetEventRaiser();
}

public static void Raise<TEventSource>(this TEventSource mock,
Action<TEventSource> eventSubscription, object sender, EventArgs args)
{

var eventRaiser = GetEventRaiserFromSubscription(mock,
eventSubscription);
eventRaiser.Raise(sender, args);
}

public static void Raise<TEventSource>(this TEventSource mock,
Action<TEventSource> eventSubscription, params object[] args) {

var eventRaiser = GetEventRaiserFromSubscription(mock,
eventSubscription);
eventRaiser.Raise(args);
}

public static void Raise<TEventSource>(this TEventSource mock,
Action<TEventSource> eventSubscription) {

var eventRaiser = GetEventRaiserFromSubscription(mock,
eventSubscription);
eventRaiser.Raise(mock, EventArgs.Empty);
}
}

Be interested to get feedback on this.

I wrote up the details (including the traditional approaches to
raising events) here:
http://davesquared.blogspot.com/2008/06/yet-another-way-of-raising-events-from.html

Regards,
David

Ayende Rahien

unread,
Jun 23, 2008, 10:38:20 PM6/23/08
to Rhino...@googlegroups.com
I think this is cool.
I am still bitter about C#, but that is another matter.
Can you create a patch for this?

David Tchepak

unread,
Jun 23, 2008, 10:56:13 PM6/23/08
to Rhino.Mocks
Agreed on the C# limitations :)
I'll have a go at creating a patch after work today and post it here.
Regards,
David

On Jun 24, 12:38 pm, "Ayende Rahien" <aye...@ayende.com> wrote:
> I think this is cool.
> I am still bitter about C#, but that is another matter.
> Can you create a patch for this?
>
...

David Tchepak

unread,
Jun 24, 2008, 10:11:27 AM6/24/08
to Rhino.Mocks
Here's my attempt at a patch. I'm in unfamiliar territory here, so please point out all my mistakes so I can fix them. :)

I've added the implementation to RhinoMocksExtensions.cs, and some basic tests to Rhino.Mocks.Tests.FieldsProblem.UsingEvents.

The implementation differs slightly from the initial post -- it publicly exposes IEventRaiser GetEventRaiser<TEventSource>(...) for use with replay/verify mocks (as per the second test in the patch).

Regards,
David
RaiseEventsFromExtensionMethods.patch

Ayende Rahien

unread,
Jun 25, 2008, 6:20:48 PM6/25/08
to Rhino...@googlegroups.com
Applied, thanks.

David Tchepak

unread,
Jun 25, 2008, 7:09:40 PM6/25/08
to Rhino...@googlegroups.com
Great :)

I'm happy to document it in the wiki etc, but I assume that needs to be done after 3.5 is released?

On Thu, Jun 26, 2008 at 08:20, Ayende Rahien <aye...@ayende.com> wrote:
Applied, thanks.


On Tue, Jun 24, 2008 at 5:11 PM, David Tchepak <tch...@gmail.com> wrote:
Here's my attempt at a patch. I'm in unfamiliar territory here, so please point out all my mistakes so I can fix them. :)
...

Ayende Rahien

unread,
Jun 25, 2008, 7:33:34 PM6/25/08
to Rhino...@googlegroups.com
I have started documenting it here:
http://www.ayende.com/Wiki/Rhino%20Mocks%203.5.ashx

Any help is welcome.

hemp

unread,
Aug 11, 2008, 6:47:11 PM8/11/08
to Rhino.Mocks
Ayende,

The sample code at the bottom of that page seems to be incorrect for
the current 3.5 beta.

[Test]
public void RaisingEventOnViewUsingExtensionMethod()
{
IView view = mocks.CreateMock();
Presenter p = new Presenter(view);
view.Raise(view.Load += null, this, EventArgs.Empty);
Assert.IsTrue(p.OnLoadCalled);
}

should read:
...
view.Raise(x => x.Load += null, this, EventArgs.Empty);
...

If I leave out the lambda, the C# compiler seems to get confused about
intent and I receive the following compile error:

"The type arguments for method
'Rhino.Mocks.RhinoMocksExtensions.Raise<TEventSource>(TEventSource,
System.Action<TEventSource>, object, System.EventArgs)' cannot be
inferred from the usage. Try specifying the type arguments
explicitly."

Ayende Rahien

unread,
Aug 12, 2008, 6:25:35 PM8/12/08
to Rhino...@googlegroups.com
Please fix this, it is a wiki, after all.

David Tchepak

unread,
Aug 12, 2008, 7:28:40 PM8/12/08
to Rhino...@googlegroups.com
'Twas my fault. Fixed now.

Thanks,
David
Reply all
Reply to author
Forward
0 new messages