/// <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));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Gets the behavior for the current invocation.
        /// </summary>
        public static IBehavior GetBehavior()
        {
            if (lastPipeline.Value != null)
            {
                return(lastPipeline.Value);
            }

            // This behavior is key to enabling static extension methods
            // on arbitrary types and allow transparent "recording"
            // behavior. The moment an extension method such as
            // Returns<T>(this T target, T value) invokes this GetBehavior
            // method, we assume the most recent call (the retrieval of
            // a property value, or invocation of a method that returns
            // some value T) was intended for matching purposes only,
            // so we need to "unwind" it and build a pipeline with it
            // so that it can be further customized by the extension method
            // implementation.

            // Here's what we do:
            // Use last invocation, argument matchers,
            // actual invocation arguments, build
            // list of matchers for all arguments,
            // and add pipeline to mock.
            if (lastInvocation.Value == null)
            {
                throw new InvalidOperationException("There is no mock being called.");
            }

            var currentMatchers = argumentMatchers.Value;
            var finalMatchers   = new List <IArgumentMatcher>();
            var invocation      = lastInvocation.Value;
            var parameters      = invocation.Method.GetParameters();

            for (int i = 0; i < invocation.Arguments.Length; i++)
            {
                var argument  = invocation.Arguments[i];
                var parameter = parameters[i];

                if (Object.Equals(argument, DefaultValue.For(parameter.ParameterType)) &&
                    currentMatchers.Count != 0 &&
                    parameter.ParameterType.IsAssignableFrom(currentMatchers.Peek().ArgumentType))
                {
                    finalMatchers.Add(currentMatchers.Pop());
                }
                else
                {
                    finalMatchers.Add(new Arguments.ConstantMatcher(parameter.ParameterType, argument));
                }
            }

            lastPipeline.Value = new Behavior(
                invocation.Mock.DefaultBehavior,
                invocation.Mock.SelectorFactory.CreateSelector(invocation, finalMatchers));

            invocation.Mock.Invocations.Remove(CallContext.LastInvocation);

            return(lastPipeline.Value);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Gets the behavior pipeline for the current invocation.
        /// </summary>
        /// <returns></returns>
        public static BehaviorPipeline GetBehavior()
        {
            if (lastPipeline.Value != null)
            {
                return(lastPipeline.Value);
            }

            // Use last invocation, argument matchers,
            // actual invocation arguments, build
            // list of matchers for all arguments,
            // and add pipeline to mock.
            // Clean last invocation and matchers,
            // as well as the actual mock invocation
            // that was tracked, as it was used
            // for recording purposes.
            if (lastInvocation.Value == null)
            {
                throw new InvalidOperationException("There is no mock being called.");
            }

            var currentMatchers = argumentMatchers.Value;
            var finalMatchers   = new List <IArgumentMatcher>();
            var invocation      = lastInvocation.Value;
            var parameters      = invocation.Method.GetParameters();

            for (int i = 0; i < invocation.Arguments.Length; i++)
            {
                var argument  = invocation.Arguments[i];
                var parameter = parameters[i];

                if (Object.Equals(argument, DefaultValue.For(parameter.ParameterType)) &&
                    currentMatchers.Count != 0 &&
                    parameter.ParameterType.IsAssignableFrom(currentMatchers.Peek().ArgumentType))
                {
                    finalMatchers.Add(currentMatchers.Pop());
                }
                else
                {
                    finalMatchers.Add(new Arguments.ConstantMatcher(parameter.ParameterType, argument));
                }
            }

            lastPipeline.Value = new BehaviorPipeline(new Behaviors.ReturnDefaultValue(), finalMatchers);

            return(lastPipeline.Value);
        }