Skip to content

Issue with System.Reflection.Missing object passed as an argument to mocked Method #107

Open
mity1982 opened this Issue Apr 26, 2014 · 1 comment

1 participant

@mity1982

I am using moq with Office Interop. For some reason default value for optional argument in property Worksheet.Range, is set to System.Reflection.Missing this leads to an exception when Mocked delegate is invoked via DynamicInvoke method in

public static object InvokePreserveStack(this Delegate del, params object[] args)

with one of the arguments set to System.Reflection.Missing.

Following code reproduces problem (might have some bug as it is converted from VB. Net).

public void ReflectionTest()
{
    Mock<Excel._Worksheet> xrm = new Mock<Excel._Worksheet>();

xrm.Setup(f => f.Range(It.IsAny<string>)).Returns(new Func<object, object, Excel.Range>(RangeReturnFunction))

    object k = xrm.Object.Range("A1");

}

public Excel.Range RangeReturnFunction(object s, object xv = null)
{
    Mock<Excel.Range> z = new Mock<Excel.Range>();
    return z.Object;
}
@mity1982

My proposal for fixing the issue.
Add new interception strategy
Interceptor.cs

        private IEnumerable<IInterceptStrategy> InterceptionStrategies()
        {
            yield return new HandleDestructor();
            yield return new HandleTracking();
            yield return new InterceptMockPropertyMixin();
            yield return new InterceptToStringMixin();
                        yield return new InterceptMissingValuesProperties();
            yield return new AddActualInvocation();
            yield return new ExtractProxyCall();
            yield return new ExecuteCall();
            yield return new InvokeBase();
            yield return new HandleMockRecursion();
        }

InterceptorStrategies.cs

    internal class InterceptMissingValuesProperties : IInterceptStrategy
    {
        public InterceptionAction HandleIntercept(ICallContext invocation, InterceptorContext ctx, CurrentInterceptContext localctx)
        {

            for (int i = 0; i < invocation.Arguments.Length; i++)
            {
                if (invocation.Arguments[i] == System.Reflection.Missing.Value)
                invocation.SetArgumentValue(i,null);
            }

            return InterceptionAction.Continue;
        }
    }

My setup code

xrm.Setup(f => f.Range(It.IsAny<string>,null)).Returns(new Func<object, object, Excel.Range>(RangeReturnFunction))

tested, works

only issue - i have to add null in setup in the place of optional argument. That is because if i don't moq will create constant matcher for "System.Reflection.Missing" which i relpace with null.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.