Пример #1
0
        private static MethodInfo GetMethodByName(Type type, Type returnType, string memberName, ref object[] args)
        {
            if (type.IsProxy())
            {
                type = type.BaseType;
            }

            var candidateMethods = type.GetAllMethods()
                                   .Where(m => m.Name == memberName)
                                   .Concat(type.GetAllProperties()
                                           .Where(p => p.Name == memberName)
                                           .SelectMany(p => new[] { p.GetGetMethod(true), p.GetSetMethod(true) })
                                           .Where(m => m != null))
                                   .Select(m =>
            {
                if (m.IsGenericMethodDefinition &&
                    returnType != typeof(void) &&
                    m.GetGenericArguments().Length == 1 &&
                    m.ReturnType.ContainsGenericParameters)
                {
                    var generics = new Dictionary <Type, Type>();
                    if (MockingUtil.GetGenericsTypesFromActualType(m.ReturnType, returnType, generics))
                    {
                        return(m.MakeGenericMethod(generics.Values.Single()));
                    }
                }
                return(m);
            })
                                   .ToArray();

            MethodInfo mockedMethod = null;

            if (candidateMethods.Length == 1)
            {
                var singleCandidate   = candidateMethods[0];
                var returnTypeMatches = ReturnTypeMatches(returnType, singleCandidate);
                var argsIgnored       = args == null || args.Length == 0;
                if (returnTypeMatches && argsIgnored)
                {
                    mockedMethod = singleCandidate;
                    args         = mockedMethod.GetParameters()
                                   .Select(p =>
                    {
                        var byref     = p.ParameterType.IsByRef;
                        var paramType = byref ? p.ParameterType.GetElementType() : p.ParameterType;
                        if (paramType.IsPointer)
                        {
                            paramType = typeof(IntPtr);
                        }
                        var isAny = (Expression)typeof(ArgExpr).GetMethod("IsAny").MakeGenericMethod(paramType).Invoke(null, null);
                        if (byref)
                        {
                            isAny = ArgExpr.Ref(isAny);
                        }
                        return(isAny);
                    })
                                   .ToArray();
                }
            }

            if (mockedMethod == null)
            {
                mockedMethod = FindMethodBySignature(candidateMethods, returnType, args);
                if (mockedMethod == null && returnType == typeof(void))
                {
                    mockedMethod = FindMethodBySignature(candidateMethods, null, args);
                }
            }

            if (mockedMethod == null)
            {
                var mockedProperty = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
                                     .FirstOrDefault(property => property.Name == memberName);
                if (mockedProperty != null)
                {
                    var getter = mockedProperty.GetGetMethod(true);
                    if (getter != null && getter.ArgumentsMatchSignature(args))
                    {
                        mockedMethod = getter;
                    }

                    if (mockedMethod == null)
                    {
                        var setter = mockedProperty.GetSetMethod(true);
                        if (setter != null && setter.ArgumentsMatchSignature(args))
                        {
                            mockedMethod = setter;
                        }
                    }

                    if (mockedMethod == null)
                    {
                        throw new MissingMemberException(BuildMissingMethodMessage(type, mockedProperty, memberName));
                    }
                }
            }

            if (mockedMethod == null)
            {
                throw new MissingMemberException(BuildMissingMethodMessage(type, null, memberName));
            }

            if (mockedMethod.ContainsGenericParameters)
            {
                mockedMethod = MockingUtil.GetRealMethodInfoFromGeneric(mockedMethod, args);
            }

            if (mockedMethod.DeclaringType != mockedMethod.ReflectedType)
            {
                mockedMethod = GetMethodByName(mockedMethod.DeclaringType, returnType, memberName, ref args);
            }

            return(mockedMethod);
        }