Alternate syntax for raising events from mocks

瀏覽次數:71 次
跳到第一則未讀訊息

David Tchepak

未讀,
2008年6月23日 晚上9:57:002008/6/23
收件者: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

未讀,
2008年6月23日 晚上10:38:202008/6/23
收件者: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

未讀,
2008年6月23日 晚上10:56:132008/6/23
收件者: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

未讀,
2008年6月24日 上午10:11:272008/6/24
收件者: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

未讀,
2008年6月25日 下午6:20:482008/6/25
收件者:Rhino...@googlegroups.com
Applied, thanks.

David Tchepak

未讀,
2008年6月25日 晚上7:09:402008/6/25
收件者: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

未讀,
2008年6月25日 晚上7:33:342008/6/25
收件者:Rhino...@googlegroups.com
I have started documenting it here:
http://www.ayende.com/Wiki/Rhino%20Mocks%203.5.ashx

Any help is welcome.

hemp

未讀,
2008年8月11日 下午6:47:112008/8/11
收件者: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

未讀,
2008年8月12日 下午6:25:352008/8/12
收件者:Rhino...@googlegroups.com
Please fix this, it is a wiki, after all.

David Tchepak

未讀,
2008年8月12日 晚上7:28:402008/8/12
收件者:Rhino...@googlegroups.com
'Twas my fault. Fixed now.

Thanks,
David
回覆所有人
回覆作者
轉寄
0 則新訊息