Beispiel #1
0
        public static Mock <TResult> FluentMock <T, TResult>(this Mock <T> mock, Expression <Func <T, TResult> > setup)
            where T : class
            where TResult : class
        {
            Guard.NotNull(mock, nameof(mock));
            Guard.NotNull(setup, nameof(setup));
            Guard.Mockable(typeof(TResult));

            MethodInfo info;

            if (setup.Body.NodeType == ExpressionType.MemberAccess)
            {
                var memberExpr = ((MemberExpression)setup.Body);
                memberExpr.ThrowIfNotMockeable();

                info = ((PropertyInfo)memberExpr.Member).GetGetMethod();
            }
            else if (setup.Body.NodeType == ExpressionType.Call)
            {
                info = ((MethodCallExpression)setup.Body).Method;
            }
            else
            {
                throw new NotSupportedException(string.Format(Resources.UnsupportedExpression, setup.ToStringFixed()));
            }

            Guard.Mockable(info.ReturnType);

            Mock fluentMock;
            MockWithWrappedMockObject innerMock;

            if (mock.InnerMocks.TryGetValue(info, out innerMock))
            {
                fluentMock = innerMock.Mock;
            }
            else
            {
                fluentMock = ((IMocked)mock.GetDefaultValue(info, useAlternateProvider: DefaultValueProvider.Mock)).Mock;
                Mock.SetupAllProperties(fluentMock);

                innerMock = new MockWithWrappedMockObject(fluentMock, fluentMock.Object);
                //                                                    ^^^^^^^^^^^^^^^^^
                // NOTE: Above, we are assuming that a default value was returned that is neither a `Task<T>` nor a `ValueTask<T>`,
                // i.e. nothing we'd need to first "unwrap" to get at the actual mocked object. This assumption would seem permissible
                // since the present method gets called only for multi-dot expressions ("recursive mocking"), which do not allow
                // `await` expressions. Therefore we don't need to deal with `Task<T>` nor `ValueTask<T>`, and we proceed as if the
                // returned default value were already "unwrapped".
            }

            var result = (TResult)innerMock.WrappedMockObject;

            mock.Setup(setup).Returns(result);

            return((Mock <TResult>)fluentMock);
        }
Beispiel #2
0
        /// <summary>
        /// Retrieves a fluent mock from the given setup expression.
        /// </summary>
        private static Mock <TResult> FluentMock <T, TResult>(Mock <T> mock, Expression <Func <T, TResult> > setup)
            where T : class
            where TResult : class
        {
            Guard.NotNull(mock, nameof(mock));
            Guard.NotNull(setup, nameof(setup));
            Guard.Mockable(typeof(TResult));

            MethodInfo info;
            IReadOnlyList <Expression> arguments;

            if (setup.Body.NodeType == ExpressionType.MemberAccess)
            {
                var memberExpr = ((MemberExpression)setup.Body);
                memberExpr.ThrowIfNotMockeable();

                info      = ((PropertyInfo)memberExpr.Member).GetGetMethod();
                arguments = new Expression[0];
            }
            else if (setup.Body.NodeType == ExpressionType.Call)
            {
                var callExpr = (MethodCallExpression)setup.Body;

                info      = callExpr.Method;
                arguments = callExpr.Arguments;
            }
            else
            {
                throw new NotSupportedException(string.Format(Resources.UnsupportedExpression, setup.ToStringFixed()));
            }

            Guard.Mockable(info.ReturnType);

            Mock   fluentMock;
            object result;

            if (mock.Setups.GetInnerMockSetups().TryFind(new InvocationShape(setup, info, arguments), out var inner))
            {
                Debug.Assert(inner.TryGetReturnValue(out _));                  // guaranteed by .GetInnerMockSetups()

                fluentMock = inner.GetInnerMock();
                _          = inner.TryGetReturnValue(out result);
            }
            else
            {
                result = mock.GetDefaultValue(info, out fluentMock, useAlternateProvider: DefaultValueProvider.Mock);
                Debug.Assert(fluentMock != null);

                Mock.SetupAllProperties(fluentMock);
            }

            mock.AddInnerMockSetup(info, arguments, setup, result);

            return((Mock <TResult>)fluentMock);
        }
Beispiel #3
0
 private MethodInfo GetTargetMethod(Type objectType, Type returnType)
 {
     // dte.Solution =>
     if (this.setupRightmost && this.isAtRightmost)
     {
         //.Setup(mock => mock.Solution)
         return(typeof(Mock <>)
                .MakeGenericType(objectType)
                .GetMethods("Setup")
                .First(m => m.IsGenericMethod)
                .MakeGenericMethod(returnType));
     }
     else
     {
         //.FluentMock(mock => mock.Solution)
         Guard.Mockable(returnType);
         return(FluentMockMethod.MakeGenericMethod(objectType, returnType));
     }
 }
Beispiel #4
0
        public Mock(MockBehavior behavior, params object[] args)
        {
            Guard.Mockable(typeof(T));

            if (args == null)
            {
                args = new object[] { null };
            }

            this.additionalInterfaces    = new List <Type>();
            this.behavior                = behavior;
            this.configuredDefaultValues = new Dictionary <Type, object>();
            this.constructorArguments    = args;
            this.defaultValueProvider    = DefaultValueProvider.Empty;
            this.eventHandlers           = new EventHandlerCollection();
            this.invocations             = new InvocationCollection();
            this.name     = CreateUniqueDefaultMockName();
            this.setups   = new SetupCollection();
            this.switches = Switches.Default;

            this.CheckParameters();
        }
Beispiel #5
0
 private static MethodInfo GetTargetMethod(Type objectType, Type returnType)
 {
     Guard.Mockable(returnType);
     return(FluentMockGenericMethod.MakeGenericMethod(objectType, returnType));
 }