I was writing some unit tests using JustMock and was pretty happy with myself that they were all passing until I tried to get one to fail. This unit test passes:
[TestFixture]
public class TestEventAggregation
{
class BaseEventArgs : EventArgs {}
class DerivedEventArgs : BaseEventArgs {}
class EventAggregationService
{
private Subject<object> _subject = new Subject<object>();
public IDisposable Subscribe<TEventArgs>(EventHandler<TEventArgs> eventHandler)
where TEventArgs : EventArgs
{
return _subject.OfType<EventPattern<TEventArgs>>().Subscribe(
delegate(EventPattern<TEventArgs> pattern)
{
eventHandler(pattern.Sender, pattern.EventArgs);
}
);
}
public void Publish<TEventArgs>(object sender, TEventArgs eventArgs)
where TEventArgs : EventArgs
{
_subject.OnNext(new EventPattern<TEventArgs>(sender, eventArgs));
}
}
[Test]
public void BaseEventIsPublishedToBaseEventSubcriberButNotDerivedEventSubscriber()
{
EventAggregationService eventAggregationService = new EventAggregationService();
// Arrange
Action<object, BaseEventArgs> baseEventHandler = Mock.Create<Action<object, BaseEventArgs>>();
Mock.Arrange(() => baseEventHandler(Arg.AnyObject, Arg.IsAny<BaseEventArgs>())).OccursOnce();
Action<object, DerivedEventArgs> derivedEventHandler = Mock.Create<Action<object, DerivedEventArgs>>();
Mock.Arrange(() => derivedEventHandler(Arg.AnyObject, Arg.IsAny<DerivedEventArgs>())).OccursOnce();
// Act
using (eventAggregationService.Subscribe(new EventHandler<BaseEventArgs>((s, e) => baseEventHandler(s, e))))
using (eventAggregationService.Subscribe(new EventHandler<DerivedEventArgs>((s, e) => derivedEventHandler(s, e))))
{
eventAggregationService.Publish(this, new BaseEventArgs());
}
// Assert
Mock.Assert(baseEventHandler);
Mock.Assert(derivedEventHandler);
}
}
It should fail, I put a break point in each of the lambdas and the base is called but not the derived. I have tried shifting and twisting things but I can't for the life of me figure out why this test passes since the derived handler is confirmed to not be called.
To build this yourself add a reference to nunit, JustMock and Rx-Linq NuGet packages.
Ah, you've found a bug. I've just pushed the fix for it to master. The fix will be released with the next internal build.
As a workaround, you can assert the call to the event handler explicitly:
Mock.Assert(() => baseEventHandler(null, null), Args.Ignore(), Occurs.Once());
Mock.Assert(() => derivedEventHandler(null, null), Args.Ignore(), Occurs.Never());