Export to GitHub

moq - issue #325

An exception is thrown when you attempt to subscribe to a stubbed event and Mock<T>.CallBase is true


Posted on Sep 12, 2011 by Helpful Bear

Just upgraded to 4.0.10827.0 from 4.0.812.4, and it appears that a bug has been introduced that causes an exception to be thrown when you subscribe to a stubbed event and Mock<T>.CallBase is true.

@Repro:

Given the following interface:

public interface IFoo
{
    event EventHandler Event;
}

Run the following code:

Mock&lt;IFoo&gt; foo = new Mock&lt;IFoo&gt;();
foo.CallBase = true;
foo.Object.Event += (sender, e) =&gt; { };

@Expected: No exception to be thrown. @Actual:

Unhandled Exception: System.NotImplementedException: This is a DynamicProxy2 error: The interceptor attempted to 'Proceed' for method 'Void add_Event(System.EventHandler)' which has no target. When calling method without target there is no implementation to 'proceed' to and it is the responsibility of the interceptor t o mimic the implementation (set return value, out arguments etc) at Castle.DynamicProxy.AbstractInvocation.ThrowOnNoTarget() at Castle.DynamicProxy.CompositionInvocation.EnsureValidTarget() at Castle.Proxies.Invocations.IFoo_add_Event.InvokeMethodOnTarget() at Castle.DynamicProxy.AbstractInvocation.Proceed() at Moq.Proxy.CastleProxyFactory.CallContext.InvokeBase() at Moq.Interceptor.Intercept(ICallContext invocation) at Moq.Proxy.CastleProxyFactory.Interceptor.Intercept(IInvocation invocation) at Castle.DynamicProxy.AbstractInvocation.Proceed() at Castle.Proxies.IFooProxy.add_Event(EventHandler value)

Comment #1

Posted on Sep 13, 2011 by Quick Monkey

CallBase = true for interfaces doesn't make sense, as there's no "base" implementation to call ;).

Yes, setting up such a property on an interface mock should throw right-away rather than later with a cryptic message.

Thanks for reporting this.

Comment #2

Posted on Jun 14, 2012 by Helpful Ox

CallBase = true doesn't make sence for mocks of interfaces, right. However, it does make sence for mocks of classes with additional interfaces (via As() method). And in that case the same exception is thrown.

Comment #3

Posted on Jun 15, 2012 by Quick Monkey

Mmm... doing As on mocks of base classes which already implement T hasn't been explicitly designed. Have you tried it out how it works?

Comment #4

Posted on Jun 15, 2012 by Helpful Ox

No, I'm speaking of mocking a class C that doesn't implement interface I. The interface is added to the mock via As(). However class C has many methods and we need them to work in tests as usually so we use CallBase = true. But the interface I doesn't have any "base".

The interface I has an event E. We want to be able to add handlers for the event and raise it via Raise(Action, EventArgs) method. However adding a handler throws exception since there is no base implementation for the handler.

Comment #5

Posted on Jun 15, 2012 by Quick Monkey

Got it!

Feeling courageous? Would be great if you could give us a hand in fixing this :)

https://github.com/Moq/moq4

Also, if you do work on the issue, plz create a Github issue for this so you can associate with the commits/pull request.

Thanks!

Status: Accepted

Labels:
Type-Defect Priority-Medium Milestone-Release4.5