Search code examples
unit-testingjustmock

JustMock unit test passing when it should fail


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.


Solution

  • 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());