Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
mity1982 opened this issue Apr 26, 2014 · 3 comments

Comments

@mity1982
Copy link

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
Copy link
Author

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.

@stakx
Copy link
Contributor

stakx commented Jun 27, 2017

Hi @mity1982, I was going to look into this, but I can't actually get your repro code to compile (on VS 2015, referencing Moq 4.7.63 and Microsoft.Office.Interop.Excel version 15). The compiler won't allow access to property f.Range as if it were a method. Also, the compiler forbids omitting optional arguments (in an expression tree).

If you are still interested in having this issue looked at, could you please provide an updated repro code that compiles without errors?

@stakx
Copy link
Contributor

stakx commented Jul 10, 2017

Closing this due to inactivity. If you still want to have this looked into, just reply with repro code and we can reopen this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants