
moq - issue #325
An exception is thrown when you attempt to subscribe to a stubbed event and Mock<T>.CallBase is true
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<IFoo> foo = new Mock<IFoo>();
foo.CallBase = true;
foo.Object.Event += (sender, e) => { };
@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 MonkeyCallBase = 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 OxCallBase = 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 MonkeyMmm... 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 OxNo, 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 MonkeyGot it!
Feeling courageous? Would be great if you could give us a hand in fixing this :)
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