Beispiel #1
0
        /// <summary>
        /// Gets or sets the value of the given property as an entry in the mock <see cref="IMock.State"/>.
        /// </summary>
        public IMethodReturn Execute(IMethodInvocation invocation, GetNextBehavior next)
        {
            if (invocation == null)
            {
                throw new ArgumentNullException(nameof(invocation));
            }

            var state = (invocation.Target as IMocked ?? throw new ArgumentException(ThisAssembly.Strings.TargetNotMock, nameof(invocation)))
                        .Mock.State;

            if (invocation.MethodBase.Name.StartsWith("get_", StringComparison.Ordinal) &&
                state.TryGetValue <object>("_" + invocation.MethodBase.Name.Substring(4), out var value))
            {
                return(invocation.CreateValueReturn(value));
            }

            if (invocation.MethodBase.Name.StartsWith("set_", StringComparison.Ordinal) &&
                (!SetterRequiresSetup || SetupScope.IsActive))
            {
                state.Set("_" + invocation.MethodBase.Name.Substring(4), invocation.Arguments.GetValue(0));
                return(invocation.CreateValueReturn(null));
            }

            return(next()(invocation, next));
        }
        /// <summary>
        /// Implements the <see cref="object.GetHashCode"/> and <see cref="object.Equals(object)"/>
        /// methods.
        /// </summary>
        public IMethodReturn Execute(IMethodInvocation invocation, ExecuteHandler next)
        {
            if (invocation.MethodBase.Name == nameof(GetHashCode))
            {
                return(invocation.CreateValueReturn(RuntimeHelpers.GetHashCode(invocation.Target), invocation.Arguments));
            }
            if (invocation.MethodBase.Name == nameof(Equals))
            {
                return(invocation.CreateValueReturn(ReferenceEquals(invocation.Target, invocation.Arguments.GetValue(0)), invocation.Arguments));
            }

            return(next.Invoke(invocation, next));
        }
        /// <summary>
        /// Fills in the ref, out and return values with the defaults determined
        /// by the <see cref="DefaultValue"/> utility class.
        /// </summary>
        public IMethodReturn Execute(IMethodInvocation invocation, GetNextBehavior next)
        {
            if (invocation.MethodBase.Name == nameof(GetHashCode))
            {
                return(invocation.CreateValueReturn(RuntimeHelpers.GetHashCode(invocation.Target)));
            }
            if (invocation.MethodBase.Name == nameof(Equals))
            {
                return(invocation.CreateValueReturn(object.ReferenceEquals(invocation.Target, invocation.Arguments[0])));
            }

            return(next().Invoke(invocation, next));
        }
Beispiel #4
0
        public IMethodReturn Invoke(IMethodInvocation invocation, GetNextBehavior getNext)
        {
            if (invocation.MethodBase.DeclaringType == typeof(IMocked))
            {
                return(invocation.CreateValueReturn(this));
            }

            CallContext <IMethodInvocation> .SetData(nameof(IMethodInvocation), invocation);

            Invocations.Add(invocation);

            if (Behaviors.Count == 0)
            {
                return(getNext().Invoke(invocation, getNext));
            }

            // This is the only added functionality of this behavior, to first match
            // applicable InvokeBehaviors and execute them in sequence.
            var applicableBehaviors = Behaviors.Where(behavior => behavior.AppliesTo(invocation)).ToArray();

            if (applicableBehaviors.Length == 0)
            {
                return(getNext().Invoke(invocation, getNext));
            }

            var index = 0;

            return(applicableBehaviors[0].Invoke(invocation, () =>
            {
                ++index;
                return (index < applicableBehaviors.Length) ?
                applicableBehaviors[index].Invoke :
                getNext();
            }));
        }
Beispiel #5
0
        /// <inheritdoc />
        public IMethodReturn Invoke(IMethodInvocation invocation, GetNextBehavior getNext)
        {
            var arguments  = invocation.Arguments.ToArray();
            var parameters = invocation.MethodBase.GetParameters();

            for (var i = 0; i < parameters.Length; i++)
            {
                var parameter = parameters[i];
                // This covers both out & ref
                if (parameter.ParameterType.IsByRef)
                {
                    arguments[i] = DefaultValue.For(parameter.ParameterType);
                }
            }

            var returnValue = default(object);

            if (invocation.MethodBase is MethodInfo info &&
                info.ReturnType != typeof(void))
            {
                returnValue = DefaultValue.For(info.ReturnType);
            }

            return(invocation.CreateValueReturn(returnValue, arguments));
        }
Beispiel #6
0
        /// <summary>
        /// Fills in the ref, out and return values with the defaults determined
        /// by the <see cref="DefaultValue"/> utility class.
        /// </summary>
        IMethodReturn IStuntBehavior.Invoke(IMethodInvocation invocation, GetNextBehavior getNext)
        {
            var arguments  = invocation.Arguments.ToArray();
            var parameters = invocation.MethodBase.GetParameters();

            for (var i = 0; i < parameters.Length; i++)
            {
                var parameter = parameters[i];
                // Only provide default values for out parameters.
                // NOTE: does not touch ByRef values.
                if (parameter.IsOut)
                {
                    arguments[i] = Provider.For(parameter.ParameterType);
                }
            }

            var returnValue = default(object);

            if (invocation.MethodBase is MethodInfo info &&
                info.ReturnType != typeof(void))
            {
                returnValue = Provider.For(info.ReturnType);
            }

            return(invocation.CreateValueReturn(returnValue, arguments));
        }
Beispiel #7
0
		public IMethodReturn Invoke (IMethodInvocation invocation, GetNextBehavior getNext)
		{
			// This is where the whole Moq matching, behavior, callbacks etc. 
			// would be evaluated and provide the actual behavior.
			if (invocation.MethodBase.DeclaringType.GetTypeInfo ().IsInterface)
				return invocation.CreateValueReturn (null);

			return getNext () (invocation, getNext);
		}
Beispiel #8
0
        public IMethodReturn Invoke(IMethodInvocation invocation, GetNextBehavior getNext)
        {
            // This is where the whole Moq matching, behavior, callbacks etc.
            // would be evaluated and provide the actual behavior.
            if (invocation.MethodBase.DeclaringType.GetTypeInfo().IsInterface)
            {
                return(invocation.CreateValueReturn(null));
            }

            return(getNext() (invocation, getNext));
        }
Beispiel #9
0
        public IMethodReturn Execute(IMethodInvocation invocation, ExecuteHandler next)
        {
            var method    = targetMethods[GetHashCode(invocation.MethodBase as MethodInfo)];
            var arguments = invocation.Arguments.ToArray();

            try
            {
                var result = method.Invoke(null, arguments);
                return(invocation.CreateValueReturn(result, arguments));
            }
            catch (TargetInvocationException tie)
            {
                return(invocation.CreateExceptionReturn(tie.InnerException !));
            }
        }
Beispiel #10
0
 /// <summary>
 /// Creates the method invocation return that ends the current invocation.
 /// </summary>
 public static IMethodReturn CreateReturn <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(this IMethodInvocation invocation, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13)
 => invocation.CreateValueReturn(null, ArgumentCollection.Create(invocation.MethodBase.GetParameters(), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13));
Beispiel #11
0
 /// <summary>
 /// Creates the method invocation return that ends the current invocation for a non-void method.
 /// </summary>
 public static IMethodReturn CreateValueReturn <TResult>(this IMethodInvocation invocation, TResult result)
 => invocation.CreateValueReturn(result, invocation.Arguments);
Beispiel #12
0
 /// <summary>
 /// Creates the method invocation return that ends the current invocation for a non-void method.
 /// </summary>
 public static IMethodReturn CreateValueReturn <TResult, T1, T2, T3, T4, T5>(this IMethodInvocation invocation, TResult result, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
 => invocation.CreateValueReturn(result, ArgumentCollection.Create(invocation.MethodBase.GetParameters(), arg1, arg2, arg3, arg4, arg5));
Beispiel #13
0
 /// <summary>
 /// Creates the method invocation return that ends the current invocation for a non-void method.
 /// </summary>
 public static IMethodReturn CreateValueReturn <TResult, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(this IMethodInvocation invocation, TResult result, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10)
 => invocation.CreateValueReturn(result, ArgumentCollection.Create(invocation.MethodBase.GetParameters(), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10));
Beispiel #14
0
        public IMethodReturn Execute(IMethodInvocation invocation, GetNextBehavior next)
        {
            if (invocation.MethodBase is MethodInfo info &&
                info.ReturnType != typeof(void) &&
                info.ReturnType.CanBeIntercepted())
            {
                var result = next().Invoke(invocation, next);
                if (result.ReturnValue == null)
                {
                    // Turn the null value into a mock for the current invocation setup
                    var currentMock = ((IMocked)invocation.Target).Mock;
                    // NOTE: this invocation will throw if there isn't a matching
                    // mock for the given return type in the same assembly as the
                    // current mock. It might be tricky to diagnose at run-time,
                    // but at design-time our recursive mock analyzer should catch
                    // this with a diagnostic that the type hasn't been generated
                    // yet.
                    var recursiveMock = ((IMocked)MockFactory.Default.CreateMock(
                                             // Use the same assembly as the current target
                                             invocation.Target.GetType().GetTypeInfo().Assembly,
                                             info.ReturnType,
                                             new Type[0],
                                             new object[0])).Mock;

                    // Clone the current mock's behaviors, except for the setups and the tracking
                    // behavior which is added already by default.
                    foreach (var behavior in currentMock.Behaviors.Where(x =>
                                                                         !(x is IMockBehaviorPipeline) &&
                                                                         !(x is MockTrackingBehavior)))
                    {
                        recursiveMock.Behaviors.Add(behavior);
                    }

                    // Set up the current invocation to return the created value
                    var setup          = currentMock.GetPipeline(MockContext.CurrentSetup);
                    var returnBehavior = setup.Behaviors.OfType <ReturnsBehavior>().FirstOrDefault();
                    if (returnBehavior != null)
                    {
                        returnBehavior.Value = recursiveMock.Object;
                    }
                    else
                    {
                        setup.Behaviors.Add(new ReturnsBehavior(recursiveMock.Object));
                    }

                    // Copy over values from the result, so that outputs contain the default values.
                    var arguments  = invocation.Arguments.ToArray();
                    var parameters = invocation.MethodBase.GetParameters();
                    for (var i = 0; i < parameters.Length; i++)
                    {
                        var parameter = parameters[i];
                        if (parameter.IsOut)
                        {
                            arguments[i] = result.Outputs[parameter.Name];
                        }
                    }

                    return(invocation.CreateValueReturn(recursiveMock.Object, arguments));
                }

                return(result);
            }

            return(next().Invoke(invocation, next));
        }
Beispiel #15
0
 public IMethodReturn Execute(IMethodInvocation invocation, ExecuteHandler next)
 {
     return(invocation.CreateValueReturn(new object()));
 }
Beispiel #16
0
 /// <summary>
 /// Creates the method invocation return that ends the current invocation.
 /// </summary>
 public static IMethodReturn CreateReturn(this IMethodInvocation invocation)
 => invocation.CreateValueReturn(null, invocation.Arguments);
Beispiel #17
0
 /// <summary>
 /// Creates the method invocation return that ends the current invocation.
 /// </summary>
 public static IMethodReturn CreateReturn <T>(this IMethodInvocation invocation, T arg)
 => invocation.CreateValueReturn(null, ArgumentCollection.Create(invocation.MethodBase.GetParameters(), arg));
Beispiel #18
0
 /// <summary>
 /// Creates the method invocation return that ends the current invocation.
 /// </summary>
 public static IMethodReturn CreateReturn <T1, T2, T3, T4, T5, T6, T7>(this IMethodInvocation invocation, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
 => invocation.CreateValueReturn(null, ArgumentCollection.Create(invocation.MethodBase.GetParameters(), arg1, arg2, arg3, arg4, arg5, arg6, arg7));
Beispiel #19
0
 /// <summary>
 /// Creates the method invocation return that ends the current invocation.
 /// </summary>
 public static IMethodReturn CreateReturn <T1, T2, T3>(this IMethodInvocation invocation, T1 arg1, T2 arg2, T3 arg3)
 => invocation.CreateValueReturn(null, ArgumentCollection.Create(invocation.MethodBase.GetParameters(), arg1, arg2, arg3));