예제 #1
0
        /// <summary>
        ///     Checks the last method invocation on the mock;
        ///     if Add was invoked the unexpected match is set up;
        /// </summary>
        /// <param name="invocation">The proxied method invocation.</param>
        public void Intercept(IInvocation invocation)
        {
            try
            {
                invocation.Proceed();
            }
            finally
            {
                if (invocation.ReturnValue != null && invocation.ReturnValue is IInvocationList mockInvocations)
                {
                    if (mockInvocations.Any() && mockInvocations.Last().Method.Name.Equals("Add"))
                    {
                        Logger.LogDebug("I have detected that the previous mock invocation was an add");

                        var lastInvocation = mockInvocations.Last();
                        var methodInfo     = lastInvocation.Method;
                        var args           = lastInvocation.Arguments;

                        //We have everything we need to set up a match, so let's do it
                        var key   = args[0].ToString();
                        var value = args[1];

                        ProjectReflectionShortcuts.SetUpCacheEntryMethod(value.GetType()).Invoke(null, new[] { ((Mock <IAppCache>)invocation.Proxy).Object, key, value });
                    }
                }
            }
        }
예제 #2
0
        internal static IAppCache SetUpCacheEntryGet <T>(this IAppCache mockedCachingService, string cacheEntryKey, T cacheEntryValue)
        {
            EnsureArgument.IsNotNull(mockedCachingService, nameof(mockedCachingService));
            EnsureArgument.IsNotNullOrEmpty(cacheEntryKey, nameof(cacheEntryKey));

            Logger.LogDebug("Setting up cache entry Get/GetOrAdd for '{cacheEntryKey}' (type: '{type}'; value: '{cacheEntryValue}')", cacheEntryKey, typeof(T), cacheEntryValue);

            var cachingServiceMock = Mock.Get(mockedCachingService);

            cachingServiceMock.Setup(m => m.Get <T>(It.Is <string>(s => s.Equals(cacheEntryKey)))).Callback(() => Logger.LogDebug("Cache Get invoked")).Returns(cacheEntryValue);

            cachingServiceMock.Setup(m => m.GetOrAdd(It.Is <string>(s => s.Equals(cacheEntryKey)), It.IsAny <Func <ICacheEntry, T> >()))
            .Callback(() => Logger.LogDebug("Cache GetOrAdd invoked"))
            .Returns(cacheEntryValue);

            //Backwards compatibility
            if (ProjectReflectionShortcuts.GetOrAddWithMemoryCacheEntryOptionsMethod != null)
            {
                Logger.LogDebug("Setting up GetOrAddWithMemoryCacheEntryOptionsMethod");

                var getOrAddExpression = ExpressionHelper.CreateMethodCallExpression <IAppCache, T>(
                    ProjectReflectionShortcuts.GetOrAddWithMemoryCacheEntryOptionsMethod.MakeGenericMethod(typeof(T)),
                    Expression.Call(ProjectReflectionShortcuts.ItIsMethodWithExpressionOfFuncOfTValueAndBoolArgument(typeof(string)),
                                    ExpressionHelper.CreateMethodCallExpression <string, bool>(CoreReflectionShortcuts.StringEqualsMethodWithStringArgument,
                                                                                               Expression.Constant(cacheEntryKey, typeof(string)))),
                    Expression.Call(ProjectReflectionShortcuts.ItIsAnyMethod(typeof(Func <ICacheEntry, T>))),
                    Expression.Call(ProjectReflectionShortcuts.ItIsAnyMethod(typeof(MemoryCacheEntryOptions))));

                cachingServiceMock.Setup(getOrAddExpression).Callback(() => Logger.LogDebug("Cache GetOrAdd invoked")).Returns(cacheEntryValue);
            }

            cachingServiceMock.Setup(m => m.GetAsync <T>(It.Is <string>(s => s.Equals(cacheEntryKey))))
            .Callback(() => Logger.LogDebug("Cache GetAsync invoked"))
            .Returns(Task.FromResult(cacheEntryValue));

            cachingServiceMock.Setup(m => m.GetOrAddAsync(It.Is <string>(s => s.Equals(cacheEntryKey)), It.IsAny <Func <ICacheEntry, Task <T> > >()))
            .Callback(() => Logger.LogDebug("Cache GetOrAddAsync invoked"))
            .Returns(Task.FromResult(cacheEntryValue));

            //Backwards compatibility
            if (ProjectReflectionShortcuts.GetOrAddAsyncWithMemoryCacheEntryOptionsMethod != null)
            {
                Logger.LogDebug("Setting up GetOrAddAsyncWithMemoryCacheEntryOptionsMethod");

                var getOrAddAsyncExpression = ExpressionHelper.CreateMethodCallExpression <IAppCache, Task <T> >(
                    ProjectReflectionShortcuts.GetOrAddAsyncWithMemoryCacheEntryOptionsMethod.MakeGenericMethod(typeof(T)),
                    Expression.Call(ProjectReflectionShortcuts.ItIsMethodWithExpressionOfFuncOfTValueAndBoolArgument(typeof(string)),
                                    ExpressionHelper.CreateMethodCallExpression <string, bool>(CoreReflectionShortcuts.StringEqualsMethodWithStringArgument,
                                                                                               Expression.Constant(cacheEntryKey, typeof(string)))),
                    Expression.Call(ProjectReflectionShortcuts.ItIsAnyMethod(typeof(Func <ICacheEntry, Task <T> >))),
                    Expression.Call(ProjectReflectionShortcuts.ItIsAnyMethod(typeof(MemoryCacheEntryOptions))));

                cachingServiceMock.Setup(getOrAddAsyncExpression).Callback(() => Logger.LogDebug("Cache GetOrAddAsync invoked")).Returns(Task.FromResult(cacheEntryValue));
            }

            return(mockedCachingService);
        }
예제 #3
0
        /// <summary>
        ///     Checks the last method invocation on the mock;
        ///     if GetOrAdd or GetOrAddAsync was invoked the unexpected match is set up and the addItemFactory result will be
        ///     returned;
        ///     otherwise the default value for the specified type will be returned.
        /// </summary>
        /// <param name="type">The type of the requested default value.</param>
        /// <param name="mock">The mock on which an unexpected invocation has occurred.</param>
        /// <returns>
        ///     if GetOrAdd or GetOrAddAsync was invoked the unexpected match is set up and the addItemFactory result will be
        ///     returned;
        ///     otherwise the default value for the specified type will be returned if the last method invocation has a return
        ///     type.
        /// </returns>
        protected override object GetDefaultValue(Type type, Mock mock)
        {
            Logger.LogDebug("NoSetUpDefaultValueProvider invoked");

            var lastInvocation = mock.Invocations.Last();
            var methodInfo     = lastInvocation.Method;
            var args           = lastInvocation.Arguments;

            if (methodInfo.Name.Equals("GetOrAdd"))
            {
                //We have everything we need to set up a match, so let's do it
                var key   = args[0].ToString();
                var value = args[1].GetType().GetMethod("Invoke").Invoke(args[1], new object[] { new CacheEntryFake(key) });

                ProjectReflectionShortcuts.SetUpCacheEntryMethod(value.GetType()).Invoke(null, new[] { _mockedCachingService, key, value });

                return(value);
            }

            if (methodInfo.Name.Equals("GetOrAddAsync"))
            {
                //We have everything we need to set up a match, so let's do it
                var key        = args[0].ToString();
                var task       = args[1].GetType().GetMethod("Invoke").Invoke(args[1], new object[] { new CacheEntryFake(key) });
                var taskResult = task.GetType().GetProperty("Result").GetValue(task);

                ProjectReflectionShortcuts.SetUpCacheEntryMethod(taskResult.GetType()).Invoke(null, new[] { _mockedCachingService, key, taskResult });

                return(task);
            }

            //void method
            if (methodInfo.ReturnType == typeof(void))
            {
                return(null);
            }

            //Return default values
            if (methodInfo.ReturnType.IsGenericType && methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(Task <>))
            {
                var genericArgument = methodInfo.ReturnType.GetGenericArguments().Single();
                var defaultValue    = genericArgument.GetDefaultValue();

                return(CoreReflectionShortcuts.TaskFromResultMethod(genericArgument).Invoke(null, new[] { defaultValue }));
            }

            return(methodInfo.ReturnType.GetDefaultValue());
        }
예제 #4
0
        internal static IAppCache SetUpCacheEntryRemove <T>(this IAppCache mockedCachingService, string cacheEntryKey)
        {
            EnsureArgument.IsNotNull(mockedCachingService, nameof(mockedCachingService));
            EnsureArgument.IsNotNullOrEmpty(cacheEntryKey, nameof(cacheEntryKey));

            Logger.LogDebug("Setting up cache entry Remove for '{cacheEntryKey}'", cacheEntryKey);

            Mock.Get(mockedCachingService)
            .Setup(m => m.Remove(It.Is <string>(s => s.Equals(cacheEntryKey))))
            .Callback(() =>
            {
                Logger.LogDebug("Cache Remove invoked");
                ProjectReflectionShortcuts.SetUpCacheEntryGetMethod(typeof(T)).Invoke(null, new object[] { mockedCachingService, cacheEntryKey, default(T) });
            });

            return(mockedCachingService);
        }