Best JustMockLite code snippet using Telerik.JustMock.Core.DynamicProxyInterceptor.Intercept
MocksRepository.cs
Source:MocksRepository.cs  
...56        private readonly Dictionary<MethodBase, MethodInfoMatcherTreeNode> invocationTreeRoots = new Dictionary<MethodBase, MethodInfoMatcherTreeNode>();57        private readonly Dictionary<KeyValuePair<object, object>, object> valueStore = new Dictionary<KeyValuePair<object, object>, object>();58        private readonly HashSet<Type> arrangedTypes = new HashSet<Type>();59        private readonly HashSet<Type> disabledTypes = new HashSet<Type>();60        private readonly HashSet<MethodBase> globallyInterceptedMethods = new HashSet<MethodBase>();61        private readonly RepositorySharedContext sharedContext;62        private readonly MocksRepository parentRepository;63        private readonly List<WeakReference> controlledMocks = new List<WeakReference>();64        private bool isRetired;65        internal static readonly HashSet<Type> KnownUnmockableTypes = new HashSet<Type>66            {67                typeof(ValueType),68                typeof(Enum),69                typeof(Delegate),70                typeof(MulticastDelegate),71                typeof(Array),72                typeof(String),73                typeof(IntPtr),74                typeof(UIntPtr),75                typeof(void),76#if !PORTABLE77                typeof(AppDomain),78                typeof(TypedReference),79                typeof(RuntimeArgumentHandle),80                Type.GetType("System.ContextBoundObject"),81                Type.GetType("System.ArgIterator"),82#endif83#if !SILVERLIGHT84                Type.GetType("System.__ComObject"),85#endif86#if SILVERLIGHT87                typeof(WeakReference),88#endif89            };90        internal IRecorder Recorder91        {92            get { return this.sharedContext.Recorder; }93        }94        internal bool IsRetired95        {96            get97            {98                return this.isRetired99                    || (this.parentRepository != null && this.parentRepository.IsRetired)100#if !PORTABLE101 || !this.creatingThread.IsAlive102#endif103;104            }105            set106            {107                this.isRetired = value;108            }109        }110        internal bool IsParentToAnotherRepository { get; private set; }111        internal MethodBase Method { get; private set; }112        internal DynamicProxyInterceptor Interceptor { get; private set; }113        internal List<IMatcher> MatchersInContext { get; private set; }114        internal int RepositoryId { get { return this.repositoryId; } }115        static MocksRepository()116        {117#if !COREFX118            var badApples = new[]119            {120                typeof(System.Security.Permissions.SecurityAttribute),121                typeof(System.Runtime.InteropServices.MarshalAsAttribute),122                typeof(object).Assembly.GetType("System.Runtime.InteropServices.TypeIdentifierAttribute"),123            };124            foreach (var unmockableAttr in badApples.Where(t => t != null))125                AttributesToAvoidReplicating.Add(unmockableAttr);126#endif127#if !PORTABLE128            mockFactory = new DynamicProxyMockFactory();129#else130            mockFactory = new StaticProxy.StaticProxyMockFactory();131#endif132            ProfilerInterceptor.Initialize();133#if DEBUG134            if (ProfilerInterceptor.IsProfilerAttached)135            {136                var logLevelEnvVar = Environment.GetEnvironmentVariable("JUSTMOCK_LOG_LEVEL");137                LogLevel logLevel;138                if (Enum.TryParse(logLevelEnvVar, out logLevel))139                {140                    DefaultLogLevel.Value = logLevel;141                }142            }143#endif144        }145        internal MocksRepository(MocksRepository parentRepository, MethodBase method)146        {147            this.repositoryId = Interlocked.Increment(ref repositoryCounter);148            this.Method = method;149            this.creatingThread = Thread.CurrentThread;150            this.Interceptor = new DynamicProxyInterceptor(this);151            this.MatchersInContext = new List<IMatcher>();152            if (parentRepository != null)153            {154                this.parentRepository = parentRepository;155                this.sharedContext = parentRepository.sharedContext;156                parentRepository.IsParentToAnotherRepository = true;157                CopyConfigurationFromParent();158            }159            else160            {161                this.sharedContext = new RepositorySharedContext();162            }163            ProfilerInterceptor.IsInterceptionEnabled = true;164            DebugView.TraceEvent(IndentLevel.Configuration, () => String.Format("Created mocks repository #{0} for {1}", this.repositoryId, this.Method));165        }166        internal static IMockMixin GetMockMixin(object obj, Type objType)167        {168            IMockMixin asMixin = GetMockMixinFromAnyMock(obj);169            if (asMixin != null)170            {171                return asMixin;172            }173            if (obj != null && objType == null)174            {175                objType = obj.GetType();176            }177            if (obj != null)178            {179                asMixin = GetMixinFromExternalDatabase(obj, objType);180            }181            else if (objType != null)182            {183                MocksRepository repo = MockingContext.ResolveRepository(UnresolvedContextBehavior.CreateNewContextual);184                if (repo != null)185                {186                    lock (repo.staticMixinDatabase)187                        repo.staticMixinDatabase.TryGetValue(objType, out asMixin);188                }189            }190            return asMixin;191        }192        private static IMockMixin GetMockMixinFromAnyMock(object mock)193        {194            var asMixin = MockingProxy.GetMockMixin(mock);195            if (asMixin != null)196                return asMixin;197            return mock as IMockMixin;198        }199        private static IMockMixin GetMixinFromExternalDatabase(object obj, Type type)200        {201            bool isValueType = type.IsValueType;202            lock (externalMixinDatabase)203            {204                if (isValueType)205                {206                    foreach (var entry in externalMixinDatabase)207                    {208                        object otherObj = entry.Key;209                        if (AreTypesInRegistrySame(type, otherObj.GetType()))210                        {211                            bool equal = false;212                            try213                            {214                                equal = AreValueTypeObjectsInRegistryEqual(obj, otherObj);215                            }216                            catch217                            {218                                throw new MockException("Implementation of method Equals in value types must not throw for mocked instances.");219                            }220                            if (equal)221                                return entry.Value;222                        }223                    }224                }225                else226                {227                    IMockMixin result;228                    externalReferenceMixinDatabase.TryGetValue(obj, out result);229                    return result;230                }231            }232            return null;233        }234        private static bool AreTypesInRegistrySame(Type queryType, Type typeInRegistry)235        {236            if (queryType == typeInRegistry)237                return true;238            return false;239        }240        private static bool AreValueTypeObjectsInRegistryEqual(object queryObj, object objInRegistry)241        {242            return Object.Equals(queryObj, objInRegistry); // no guard - Object.Equals on a value type can't get intercepted243        }244        private MethodInfoMatcherTreeNode DeepCopy(MethodInfoMatcherTreeNode root)245        {246            var newRoot = (MethodInfoMatcherTreeNode)root.Clone();247            Queue<MatcherNodeAndParent> queue = new Queue<MatcherNodeAndParent>();248            foreach (var child in root.Children)249                queue.Enqueue(new MatcherNodeAndParent(child, newRoot));250            while (queue.Count > 0)251            {252                MatcherNodeAndParent current = queue.Dequeue();253                IMatcherTreeNode newCurrent = current.Node.Clone();254                foreach (IMatcherTreeNode node in current.Node.Children)255                {256                    queue.Enqueue(new MatcherNodeAndParent(node, newCurrent));257                }258                current.Parent.Children.Add(newCurrent);259                newCurrent.Parent = current.Parent;260            }261            return newRoot;262        }263        private void CopyConfigurationFromParent()264        {265            this.arrangementTreeRoots.Clear();266            this.invocationTreeRoots.Clear();267            this.valueStore.Clear();268            this.controlledMocks.Clear();269            if (parentRepository != null)270            {271                foreach (var root in parentRepository.arrangementTreeRoots)272                {273                    this.arrangementTreeRoots.Add(root.Key, DeepCopy(root.Value));274                }275                foreach (var root in parentRepository.invocationTreeRoots)276                {277                    this.invocationTreeRoots.Add(root.Key, DeepCopy(root.Value));278                }279                foreach (var kvp in parentRepository.valueStore)280                {281                    this.valueStore.Add(kvp.Key, kvp.Value);282                }283                foreach (WeakReference mockRef in parentRepository.controlledMocks)284                {285                    IMockMixin mixin = GetMockMixinFromAnyMock(mockRef.Target);286                    if (mixin != null)287                    {288                        mixin.Repository = this;289                        this.controlledMocks.Add(mockRef);290                    }291                }292            }293        }294        internal void Retire()295        {296            this.IsRetired = true;297            this.Reset();298        }299        internal void InterceptGlobally(MethodBase method)300        {301            if (this.globallyInterceptedMethods.Add(method))302            {303                ProfilerInterceptor.RegisterGlobalInterceptor(method, this);304            }305        }306        internal void Reset()307        {308            DebugView.TraceEvent(IndentLevel.Configuration, () => String.Format("Resetting mock repository related to {0}.", this.Method));309            foreach (var type in this.arrangedTypes)310            {311                ProfilerInterceptor.EnableInterception(type, false, this);312            }313            this.arrangedTypes.Clear();314            this.staticMixinDatabase.Clear();315            foreach (var method in this.globallyInterceptedMethods)316            {317                ProfilerInterceptor.UnregisterGlobalInterceptor(method, this);318            }319            this.globallyInterceptedMethods.Clear();320            lock (externalMixinDatabase)321            {322                foreach (WeakReference mockRef in this.controlledMocks)323                {324                    IMockMixin mock = GetMockMixinFromAnyMock(mockRef.Target);325                    if (mock != null && mock.ExternalizedMock != null && mock.Originator == this)326                    {327                        externalMixinDatabase.RemoveAll(kvp => kvp.Value == mock);328                        externalReferenceMixinDatabase.Remove(mock.ExternalizedMock);329                    }330                }331            }332            this.controlledMocks.Clear();333            this.CopyConfigurationFromParent();334        }335        internal void DispatchInvocation(Invocation invocation)336        {337            DebugView.TraceEvent(IndentLevel.DispatchResult, () => String.Format("Handling dispatch in repo #{0} servicing {1}", this.repositoryId, this.Method));338            if (this.disabledTypes.Contains(invocation.Method.DeclaringType))339            {340                invocation.CallOriginal = true;341                return;342            }343            invocation.InArrange = this.sharedContext.InArrange;344            invocation.InArrangeArgMatching = this.sharedContext.InArrangeArgMatching;345            invocation.InAssertSet = this.sharedContext.InAssertSet;346            invocation.InRunClassConstructor = this.sharedContext.RunClassConstructorCount > 0;347            invocation.Recording = this.Recorder != null;348            invocation.RetainBehaviorDuringRecording = this.sharedContext.DispatchToMethodMocks;349            invocation.Repository = this;350            bool methodMockProcessed = false;351            if (invocation.Recording)352            {353                this.Recorder.Record(invocation);354            }355            if (!invocation.Recording || invocation.RetainBehaviorDuringRecording)356            {357                methodMockProcessed = DispatchInvocationToMethodMocks(invocation);358            }359            invocation.ThrowExceptionIfNecessary();360            if (!methodMockProcessed)361            {362                // We have to be careful for the potential exception throwing in the assertion context,363                // so skip CallOriginalBehavior processing364                var mock = invocation.MockMixin;365                if (mock != null)366                {367                    var fallbackBehaviorsToExecute =368                        mock.FallbackBehaviors369                            .Where(behavior => !invocation.InAssertSet || !(behavior is CallOriginalBehavior))370                            .ToList();371                    foreach (var fallbackBehavior in fallbackBehaviorsToExecute)372                    {373                        fallbackBehavior.Process(invocation);374                    }375                }376                else377                {378                    invocation.CallOriginal = CallOriginalBehavior.ShouldCallOriginal(invocation) && !invocation.InAssertSet;379                }380            }381            if (!invocation.CallOriginal && !invocation.IsReturnValueSet && invocation.Method.GetReturnType() != typeof(void))382            {383                Type returnType = invocation.Method.GetReturnType();384                object defaultValue = null;385#if !PORTABLE386                if (returnType.BaseType != null && returnType.BaseType == typeof(Task))387                {388                    Type taskGenericArgument = returnType.GenericTypeArguments.FirstOrDefault();389                    object taskArgumentDefaultValue = taskGenericArgument.GetDefaultValue();390                    // create a task with default value to return, by using the casting help method in MockingUtil391                    MethodInfo castMethod = typeof(MockingUtil).GetMethod("TaskFromObject", BindingFlags.Static | BindingFlags.Public);392                    MethodInfo castMethodGeneric = castMethod.MakeGenericMethod(taskGenericArgument);393                    defaultValue = castMethodGeneric.Invoke(null, new object[] { taskArgumentDefaultValue });394                }395                else396#endif397                {398                    defaultValue = returnType.GetDefaultValue();399                }400                invocation.ReturnValue = defaultValue;401            }402#if !PORTABLE403            try404            {405                if (MockingContext.Plugins.Exists<IDebugWindowPlugin>())406                {407                    Func<object, Type, ObjectInfo> CreateObjectInfo = (value, type) =>408                    {409                        ObjectInfo resultInfo = (value != null) ? ObjectInfo.FromObject(value) : ObjectInfo.FromNullObject(type);410                        return resultInfo;411                    };412                    var debugWindowPlugin = MockingContext.Plugins.Get<IDebugWindowPlugin>();413                    var mockInfo = MockInfo.FromMethodBase(invocation.Method);414                    ObjectInfo[] invocationsArgInfos =415                        invocation.Args.Select(416                                (arg, index) =>417                                    {418                                        var argInfo = CreateObjectInfo(arg, invocation.Method.GetParameters()[index].ParameterType);419                                        return argInfo;420                                    }).ToArray();421                    ObjectInfo invocationInstanceInfo = ObjectInfo.FromObject(invocation.Instance ?? invocation.Method.DeclaringType);422                    ObjectInfo invocationResultInfo = CreateObjectInfo(invocation.ReturnValue, invocation.Method.GetReturnType());423                    var invocationInfo = new InvocationInfo(invocationInstanceInfo, invocationsArgInfos, invocationResultInfo);424                    debugWindowPlugin.MockInvoked(425                        invocation.Repository.RepositoryId,426                        invocation.Repository.GetRepositoryPath(),427                        mockInfo,428                        invocationInfo);429                }430            }431            catch (Exception e)432            {433                System.Diagnostics.Trace.WriteLine("Exception thrown calling IDebugWindowPlugin plugin: " + e);434            }435#endif436        }437        internal T GetValue<T>(object owner, object key, T dflt)438        {439            object value;440            if (valueStore.TryGetValue(new KeyValuePair<object, object>(owner, key), out value))441            {442                return (T)value;443            }444            else445            {446                return dflt;447            }448        }449        internal void StoreValue<T>(object owner, object key, T value)450        {451            valueStore[new KeyValuePair<object, object>(owner, key)] = value;452        }453        internal IDisposable StartRecording(IRecorder recorder, bool dispatchToMethodMocks)454        {455            return this.sharedContext.StartRecording(recorder, dispatchToMethodMocks);456        }457        internal IDisposable StartArrangeArgMatching()458        {459            return this.sharedContext.StartArrangeArgMatching();460        }461        internal void AddMatcherInContext(IMatcher matcher)462        {463            if (!this.sharedContext.InArrange || this.sharedContext.Recorder != null)464            {465                this.MatchersInContext.Add(matcher);466            }467        }468        internal object Create(Type type, MockCreationSettings settings)469        {470            object delegateResult;471            if (TryCreateDelegate(type, settings, out delegateResult))472            {473                return delegateResult;474            }475            bool isSafeMock = settings.FallbackBehaviors.OfType<CallOriginalBehavior>().Any();476            this.CheckIfCanMock(type, !isSafeMock);477            this.EnableInterception(type);478            bool canCreateProxy = !type.IsSealed;479            MockMixin mockMixinImpl = this.CreateMockMixin(type, settings);480            ConstructorInfo[] ctors = type.GetConstructors();481            bool isCoclass = ctors.Any(ctor => ctor.IsExtern());482            bool hasAdditionalInterfaces = settings.AdditionalMockedInterfaces != null && settings.AdditionalMockedInterfaces.Length > 0;483            bool hasAdditionalProxyTypeAttributes = settings.AdditionalProxyTypeAttributes != null && settings.AdditionalProxyTypeAttributes.Any();484            bool shouldCreateProxy = settings.MustCreateProxy485                || hasAdditionalInterfaces486                || isCoclass487                || type.IsAbstract || type.IsInterface488                || !settings.MockConstructorCall489                || hasAdditionalProxyTypeAttributes490                || !ProfilerInterceptor.IsProfilerAttached491                || !ProfilerInterceptor.TypeSupportsInstrumentation(type);492            bool createTransparentProxy = MockingProxy.CanCreate(type) && !ProfilerInterceptor.IsProfilerAttached;493            Exception proxyFailure = null;494            object instance = null;495            if (canCreateProxy && shouldCreateProxy)496            {497                try498                {499                    instance = mockFactory.Create(type, this, mockMixinImpl, settings, createTransparentProxy);500                }501                catch (ProxyFailureException ex)502                {503                    proxyFailure = ex.InnerException;504                }505            }506            IMockMixin mockMixin = instance as IMockMixin;507            if (instance == null)508            {509                if (type.IsInterface || type.IsAbstract)510                    throw new MockException(String.Format("Abstract type '{0}' is not accessible for inheritance.", type));511                if (hasAdditionalInterfaces)512                    throw new MockException(String.Format("Type '{0}' is not accessible for inheritance. Cannot create mock object implementing the specified additional interfaces.", type));513                if (!ProfilerInterceptor.IsProfilerAttached && !createTransparentProxy)514                    ProfilerInterceptor.ThrowElevatedMockingException(type);515                if (settings.MockConstructorCall && type.IsValueType)516                {517                    settings.MockConstructorCall = false;518                    settings.Args = null;519                }520                if (!settings.MockConstructorCall)521                {522                    try523                    {524                        instance = type.CreateObject(settings.Args);525                    }526                    catch (MissingMethodException)527                    {528                        settings.MockConstructorCall = true;529                    }530                }531                if (settings.MockConstructorCall)532                {533                    instance = MockingUtil.GetUninitializedObject(type);534                }535                if (!createTransparentProxy)536                {537                    mockMixin = this.CreateExternalMockMixin(type, instance, settings);538                }539            }540            else541            {542                this.controlledMocks.Add(new WeakReference(instance));543            }544            if (type.IsClass)545                GC.SuppressFinalize(instance);546            if (createTransparentProxy)547            {548                if (mockMixin == null)549                {550                    mockMixin = mockMixinImpl;551                }552                instance = MockingProxy.CreateProxy(instance, this, mockMixin);553            }554            mockMixin.IsInstanceConstructorMocked = settings.MockConstructorCall;555            return instance;556        }557        internal IMockMixin CreateExternalMockMixin(Type mockObjectType, object mockObject, MockCreationSettings settings)558        {559            if (mockObjectType == null)560            {561                if (mockObject == null)562                    throw new ArgumentNullException("mockObject");563                mockObjectType = mockObject.GetType();564            }565            this.EnableInterception(mockObjectType);566            if (mockObject == null)567                throw new MockException(String.Format("Failed to create instance of type '{0}'", mockObjectType));568            MockMixin mockMixin = this.CreateMockMixin(mockObjectType, settings, false);569            IMockMixin compoundMockMixin = mockFactory.CreateExternalMockMixin(mockMixin, settings.Mixins);570            lock (externalMixinDatabase)571            {572                if (mockObjectType.IsValueType())573                {574                    externalMixinDatabase.RemoveAll(kvp => kvp.Key.Equals(mockObject));575                    externalMixinDatabase.Add(new KeyValuePair<object, IMockMixin>(mockObject, compoundMockMixin));576                }577                else578                {579                    externalReferenceMixinDatabase.Add(mockObject, compoundMockMixin);580                }581                compoundMockMixin.ExternalizedMock = mockObject;582                this.controlledMocks.Add(new WeakReference(compoundMockMixin));583            }584            return compoundMockMixin;585        }586        internal ProxyTypeInfo CreateClassProxyType(Type classToProxy, MockCreationSettings settings)587        {588            MockMixin mockMixinImpl = this.CreateMockMixin(classToProxy, settings);589            return mockFactory.CreateClassProxyType(classToProxy, this, settings, mockMixinImpl);590        }591        private void CheckIfCanMock(Type type, bool checkSafety)592        {593            if (KnownUnmockableTypes.Contains(type)594                || typeof(Delegate).IsAssignableFrom(type))595                throw new MockException("Cannot create mock for type due to CLR limitations.");596            if (checkSafety)597                ProfilerInterceptor.CheckIfSafeToInterceptWholesale(type);598        }599        internal void InterceptStatics(Type type, MockCreationSettings settings, bool mockStaticConstructor)600        {601            if (!ProfilerInterceptor.IsProfilerAttached)602                ProfilerInterceptor.ThrowElevatedMockingException(type);603            if (!settings.FallbackBehaviors.OfType<CallOriginalBehavior>().Any())604                ProfilerInterceptor.CheckIfSafeToInterceptWholesale(type);605            var mockMixin = (IMockMixin)Create(typeof(ExternalMockMixin),606                new MockCreationSettings607                {608                    Mixins = settings.Mixins,609                    SupplementaryBehaviors = settings.SupplementaryBehaviors,610                    FallbackBehaviors = settings.FallbackBehaviors,611                    MustCreateProxy = true,612                });613            mockMixin.IsStaticConstructorMocked = mockStaticConstructor;614            lock (staticMixinDatabase)615                staticMixinDatabase[type] = mockMixin;616            this.EnableInterception(type);617        }618        private MockMixin CreateMockMixin(Type declaringType, MockCreationSettings settings)619        {620            return CreateMockMixin(declaringType, settings, settings.MockConstructorCall);621        }622        private MockMixin CreateMockMixin(Type declaringType, MockCreationSettings settings, bool mockConstructorCall)623        {624            var mockMixin = new MockMixin625            {626                Repository = this,627                DeclaringType = declaringType,628                IsInstanceConstructorMocked = mockConstructorCall,629            };630            foreach (var behavior in settings.SupplementaryBehaviors)631                mockMixin.SupplementaryBehaviors.Add(behavior);632            foreach (var behavior in settings.FallbackBehaviors)633                mockMixin.FallbackBehaviors.Add(behavior);634            return mockMixin;635        }636        [ArrangeMethod]637        internal TMethodMock Arrange<TMethodMock>(Expression expression, Func<TMethodMock> methodMockFactory)638            where TMethodMock : IMethodMock639        {640            TMethodMock result = methodMockFactory();641            using (this.sharedContext.StartArrange())642            {643                result.Repository = this;644                result.ArrangementExpression = ExpressionUtil.ConvertMockExpressionToString(expression);645                result.CallPattern = CallPatternCreator.FromExpression(this, expression);646                AddArrange(result);647            }648#if !PORTABLE649            var createInstanceLambda = ActivatorCreateInstanceTBehavior.TryCreateArrangementExpression(result.CallPattern.Method);650            if (createInstanceLambda != null)651            {652                var createInstanceMethodMock = Arrange(createInstanceLambda, methodMockFactory);653                ActivatorCreateInstanceTBehavior.Attach(result, createInstanceMethodMock);654            }655#endif656            return result;657        }658        /// <summary>659        /// Since we are not able to record deffered execution, check whether mock is about to present660        /// IQueryable<> or IEnumerable<>. If it so, then throw an exception to prompt the user to use661        /// Mock.Arrange overloads with expressions.662        /// See also https://stackoverflow.com/questions/3894490/linq-what-is-the-quickest-way-to-find-out-deferred-execution-or-not663        /// </summary>664        /// <typeparam name="TMethodMock">Mock return type</typeparam>665        /// <param name="methodMockFactory">Mock factory</param>666        private void CheckDefferedExecutionTypes<TMethodMock>(Func<TMethodMock> methodMockFactory)667        {668            var mockFactoryType = methodMockFactory.GetType().GetGenericArguments().FirstOrDefault();669            if (mockFactoryType.IsGenericType && mockFactoryType.GetGenericTypeDefinition() == typeof(FuncExpectation<>))670            {671                var mockFactoryGenericArguments = mockFactoryType.GetGenericArguments();672                if (mockFactoryGenericArguments673                        .Where(a => a.IsGenericType)674                        .Where(a => a.GetGenericTypeDefinition() == typeof(IQueryable<>)675                            || a.GetGenericTypeDefinition() == typeof(IEnumerable<>))676                        .Any())677                {678                    throw new MockException("Cannot arrange action with potential deffered execution, use Mock.Arrange with expressions instead.");679                }680            }681        }682        [ArrangeMethod]683        internal TMethodMock Arrange<TMethodMock>(Action memberAction, Func<TMethodMock> methodMockFactory)684            where TMethodMock : IMethodMock685        {686            using (this.sharedContext.StartArrange())687            {688                var result = methodMockFactory();689                CheckDefferedExecutionTypes(methodMockFactory);690                result.Repository = this;691                result.CallPattern = CallPatternCreator.FromAction(this, memberAction);692                AddArrange(result);693                return result;694            }695        }696        [ArrangeMethod]697        internal TMethodMock Arrange<TMethodMock>(object instance, MethodBase method, object[] arguments, Func<TMethodMock> methodMockFactory)698            where TMethodMock : IMethodMock699        {700            using (this.sharedContext.StartArrange())701            {702                var result = methodMockFactory();703                result.Repository = this;704                result.CallPattern = CallPatternCreator.FromMethodBase(this, instance, method, arguments);705                AddArrange(result);706                return result;707            }708        }709        [ArrangeMethod]710        internal TMethodMock Arrange<TMethodMock>(CallPattern callPattern, Func<TMethodMock> methodMockFactory)711            where TMethodMock : IMethodMock712        {713            using (this.sharedContext.StartArrange())714            {715                var result = methodMockFactory();716                result.Repository = this;717                result.CallPattern = callPattern;718                AddArrange(result);719                return result;720            }721        }722        private void AssertBehaviorsForMocks(IEnumerable<IMethodMock> mocks, bool ignoreMethodMockOccurrences)723        {724            foreach (var methodMock in mocks)725            {726                bool occurrenceAsserted = ignoreMethodMockOccurrences;727                if (!ignoreMethodMockOccurrences728                    && !methodMock.OccurencesBehavior.LowerBound.HasValue729                    && !methodMock.OccurencesBehavior.UpperBound.HasValue)730                {731                    methodMock.OccurencesBehavior.Assert(1, null);732                    occurrenceAsserted = true;733                }734                foreach (var behavior in methodMock.Behaviors.OfType<IAssertableBehavior>())735                    if (!occurrenceAsserted || behavior != methodMock.OccurencesBehavior)736                        behavior.Assert();737            }738        }739        internal void AssertAll(string message, object mock)740        {741            using (MockingContext.BeginFailureAggregation(message))742            {743                var mocks = GetMethodMocksFromObject(mock);744                AssertBehaviorsForMocks(mocks.Select(m => m.MethodMock), false);745            }746        }747        internal void AssertAll(string message)748        {749            using (MockingContext.BeginFailureAggregation(message))750            {751                var mocks = GetAllMethodMocks();752                AssertBehaviorsForMocks(mocks.Select(m => m.MethodMock), false);753            }754        }755        internal void Assert(string message, object mock, Expression expr = null, Args args = null, Occurs occurs = null)756        {757            using (MockingContext.BeginFailureAggregation(message))758            {759                if (expr == null)760                {761                    List<IMethodMock> mocks = new List<IMethodMock>();762                    mocks.AddRange(GetMethodMocksFromObject(mock).Select(m => m.MethodMock));763                    foreach (var methodMock in mocks)764                    {765                        foreach (var behavior in methodMock.Behaviors.OfType<IAssertableBehavior>())766                            behavior.Assert();767                    }768                    MockingUtil.UnwrapDelegateTarget(ref mock);769                    var mockMixin = GetMockMixin(mock, null);770                    if (mockMixin != null)771                    {772                        foreach (var behavior in mockMixin.FallbackBehaviors.OfType<IAssertableBehavior>()773                            .Concat(mockMixin.SupplementaryBehaviors.OfType<IAssertableBehavior>()))774                            behavior.Assert();775                    }776                }777                else778                {779                    CallPattern callPattern = CallPatternCreator.FromExpression(this, expr);780                    AssertForCallPattern(callPattern, args, occurs);781                }782            }783        }784        internal void AssertAction(string message, Action memberAction, Args args = null, Occurs occurs = null)785        {786            using (MockingContext.BeginFailureAggregation(message))787            {788                CallPattern callPattern = CallPatternCreator.FromAction(this, memberAction);789                AssertForCallPattern(callPattern, args, occurs);790            }791        }792        internal void AssertSetAction(string message, Action memberAction, Args args = null, Occurs occurs = null)793        {794            using (MockingContext.BeginFailureAggregation(message))795            {796                using (this.sharedContext.StartAssertSet())797                {798                    CallPattern callPattern = CallPatternCreator.FromAction(this, memberAction, true);799                    AssertForCallPattern(callPattern, args, occurs);800                }801            }802        }803        internal void AssertMethodInfo(string message, object instance, MethodBase method, object[] arguments, Occurs occurs)804        {805            using (MockingContext.BeginFailureAggregation(message))806            {807                CallPattern callPattern = CallPatternCreator.FromMethodBase(instance, method, arguments);808                AssertForCallPattern(callPattern, null, occurs);809            }810        }811        internal void AssertIgnoreInstance(string message, Type type, bool ignoreMethodMockOccurrences)812        {813            using (MockingContext.BeginFailureAggregation(message))814            {815                var methodMocks = GetMethodMocksFromObject(null, type);816                AssertBehaviorsForMocks(methodMocks.Select(m => m.MethodMock), ignoreMethodMockOccurrences);817            }818        }819        internal int GetTimesCalled(Expression expression, Args args)820        {821            CallPattern callPattern = CallPatternCreator.FromExpression(this, expression);822            int callsCount;823            CountMethodMockInvocations(callPattern, args, out callsCount);824            return callsCount;825        }826        internal int GetTimesCalledFromAction(Action action, Args args)827        {828            var callPattern = CallPatternCreator.FromAction(this, action);829            int callsCount;830            CountMethodMockInvocations(callPattern, args, out callsCount);831            return callsCount;832        }833        internal int GetTimesCalledFromMethodInfo(object instance, MethodBase method, object[] arguments)834        {835            var callPattern = CallPatternCreator.FromMethodBase(instance, method, arguments);836            int callsCount;837            CountMethodMockInvocations(callPattern, null, out callsCount);838            return callsCount;839        }840        private HashSet<IMethodMock> CountMethodMockInvocations(CallPattern callPattern, Args args, out int callsCount)841        {842            if (callPattern.IsDerivedFromObjectEquals)843                throw new MockException("Cannot assert calls to methods derived from Object.Equals");844            PreserveRefOutValuesBehavior.ReplaceRefOutArgsWithAnyMatcher(callPattern);845            if (args != null)846            {847                if (args.Filter != null)848                {849                    if (args.IsIgnored == null)850                    {851                        args.IsIgnored = true;852                    }853                    if (!callPattern.Method.IsStatic854                        && args.IsInstanceIgnored == null855                        && args.Filter.Method.GetParameters().Length == callPattern.Method.GetParameters().Length + 1)856                    {857                        args.IsInstanceIgnored = true;858                    }859                }860                if (args.IsIgnored == true)861                {862                    for (int i = 0; i < callPattern.ArgumentMatchers.Count; i++)863                        callPattern.ArgumentMatchers[i] = new AnyMatcher();864                }865                if (args.IsInstanceIgnored == true)866                {867                    callPattern.InstanceMatcher = new AnyMatcher();868                }869                callPattern.Filter = args.Filter;870            }871            MethodInfoMatcherTreeNode root;872            callsCount = 0;873            var mocks = new HashSet<IMethodMock>();874            var method = callPattern.Method;875            if (invocationTreeRoots.TryGetValue(method, out root))876            {877                var occurences = root.GetOccurences(callPattern);878                callsCount = occurences.Select(x => x.Calls).Sum();879                foreach (var mock in occurences.SelectMany(x => x.Mocks))880                {881                    mocks.Add(mock);882                }883            }884            return mocks;885        }886        private void AssertForCallPattern(CallPattern callPattern, Args args, Occurs occurs)887        {888            int callsCount;889            var mocks = CountMethodMockInvocations(callPattern, args, out callsCount);890            if (occurs != null)891            {892                InvocationOccurrenceBehavior.Assert(occurs.LowerBound, occurs.UpperBound, callsCount, null, null);893            }894            if (mocks.Count == 0)895            {896                MethodInfoMatcherTreeNode funcRoot;897                if (arrangementTreeRoots.TryGetValue(callPattern.Method, out funcRoot))898                {899                    var arranges = funcRoot.GetAllMethodMocks(callPattern);900                    foreach (var arrange in arranges)901                    {902                        mocks.Add(arrange.MethodMock);903                    }904                }905            }906            if (occurs == null && mocks.Count == 0)907            {908                InvocationOccurrenceBehavior.Assert(Occurs.AtLeastOnce().LowerBound, Occurs.AtLeastOnce().UpperBound, callsCount, null, null);909            }910            else911            {912                AssertBehaviorsForMocks(mocks, occurs != null);913            }914        }915        internal MethodBase GetMethodFromCallPattern(CallPattern callPattern)916        {917            var method = callPattern.Method as MethodInfo;918            if (method == null || !method.IsVirtual)919                return callPattern.Method;920            method = method.NormalizeComInterfaceMethod();921            var valueMatcher = callPattern.InstanceMatcher as IValueMatcher;922            if (valueMatcher != null && valueMatcher.Value != null)923            {924                var valueType = valueMatcher.Value.GetType();925                var mockMixin = GetMockMixin(valueMatcher.Value, null);926                var type = mockMixin != null ? mockMixin.DeclaringType : valueType;927                if (!type.IsInterface && method.DeclaringType.IsAssignableFrom(type))928                {929                    var concreteMethod = MockingUtil.GetConcreteImplementer(method, type);930                    if (!concreteMethod.IsInheritable() && !ProfilerInterceptor.IsProfilerAttached)931                    {932                        var reimplementedInterfaceMethod = (MethodInfo)method.GetInheritanceChain().Last();933                        if (reimplementedInterfaceMethod.DeclaringType.IsInterface934                            && mockFactory.IsAccessible(reimplementedInterfaceMethod.DeclaringType))935                        {936                            concreteMethod = reimplementedInterfaceMethod;937                        }938                    }939                    method = concreteMethod;940                }941            }942            if (method.DeclaringType != method.ReflectedType)943                method = (MethodInfo)MethodBase.GetMethodFromHandle(method.MethodHandle, method.DeclaringType.TypeHandle);944            return method;945        }946        /// <summary>947        /// Converts the given object to a matcher as follows. This method is most useful for948        /// creating a matcher out of an argument expression.949        /// 950        /// It works as follows:951        /// If the object is not an expression, then a value matcher for that object is returned.952        /// If the object is an expression then:953        /// * if the top of the expression is a method call expression and the member954        ///     has the ArgMatcherAttribute then the specific matcher type is instantiaded955        ///     with the parameters passed to the method call expression and returned.956        ///     If the matcher type is generic, then it is defined with the type of the expression.957        /// * if the top expression is a member or method call and the member958        ///     has the ArgIgnoreAttribute, then a TypeMatcher is returned959        /// * otherwise, the expression is evaluated and a ValueMatcher is returned960        /// </summary>961        /// <param name="argumentObj"></param>962        /// <returns></returns>963        internal static IMatcher CreateMatcherForArgument(object argumentObj)964        {965            var argExpr = argumentObj as Expression;966            if (argExpr == null)967            {968                return new ValueMatcher(argumentObj);969            }970            else971            {972                var argMatcher = TryCreateMatcherFromArgMember(argExpr);973                if (argMatcher != null)974                {975                    return argMatcher;976                }977                else978                {979                    //no matcher, evaluate the original expression980                    var argValue = argExpr.EvaluateExpression();981                    return new ValueMatcher(argValue);982                }983            }984        }985        internal static IMatcher TryCreateMatcherFromArgMember(Expression argExpr)986        {987            // The expression may end with a conversion which erases the type of the required matcher.988            // Remove the conversion before working with matchers989            while (argExpr.NodeType == ExpressionType.Convert)990                argExpr = ((UnaryExpression)argExpr).Operand;991            ArgMatcherAttribute argAttribute = null;992            Expression[] matcherArguments = null;993            if (argExpr is MethodCallExpression)994            {995                var methodCall = (MethodCallExpression)argExpr;996                argAttribute = (ArgMatcherAttribute)Attribute.GetCustomAttribute(methodCall.Method, typeof(ArgMatcherAttribute));997                matcherArguments = methodCall.Arguments.ToArray();998            }999            else if (argExpr is MemberExpression)1000            {1001                var memberExpr = (MemberExpression)argExpr;1002                argAttribute = (ArgMatcherAttribute)Attribute.GetCustomAttribute(memberExpr.Member, typeof(ArgMatcherAttribute));1003            }1004            if (argAttribute != null)1005            {1006                if (argAttribute.GetType() == typeof(ArgIgnoreAttribute))1007                {1008                    return new TypeMatcher(argExpr.Type);1009                }1010                else if (argAttribute.GetType() == typeof(ArgIgnoreTypeAttribute))1011                {1012                    var func = Expression.Lambda(argExpr).Compile();1013                    var funcResult = func.DynamicInvoke();1014                    return new TypeMatcher(funcResult.GetType());1015                }1016                else if (argAttribute.GetType() == typeof(RefArgAttribute) || argAttribute.GetType() == typeof(OutArgAttribute))1017                {1018                    var asMemberExpr = argExpr as MemberExpression;1019                    if (asMemberExpr != null)1020                    {1021                        argExpr = asMemberExpr.Expression;1022                    }1023                    var refCall = (MethodCallExpression)argExpr;1024                    var actualArg = refCall.Arguments[0];1025                    var memberExpr = actualArg as MemberExpression;1026                    if (memberExpr != null && typeof(Expression).IsAssignableFrom(memberExpr.Type) && memberExpr.Expression.Type.DeclaringType == typeof(ArgExpr))1027                    {1028                        actualArg = (Expression)actualArg.EvaluateExpression();1029                    }1030                    var argMatcher = CreateMatcherForArgument(actualArg);1031                    argMatcher.ProtectRefOut = argAttribute.GetType() == typeof(RefArgAttribute);1032                    return argMatcher;1033                }1034                else1035                {1036                    var matcherType = argAttribute.Matcher;1037                    var matcherArgs = argAttribute.MatcherArgs;1038                    if (matcherType.IsGenericTypeDefinition)1039                        matcherType = matcherType.MakeGenericType(argExpr.Type);1040                    if (matcherArgs == null && matcherArguments != null)1041                        matcherArgs = matcherArguments.Select(matcherArgExpr => matcherArgExpr.EvaluateExpression()).ToArray();1042                    var matcher = (IMatcher)MockingUtil.CreateInstance(matcherType, matcherArgs);1043                    return matcher;1044                }1045            }1046            else1047            {1048                return null;1049            }1050        }1051        private void AddArrange(IMethodMock methodMock)1052        {1053            var method = methodMock.CallPattern.Method;1054            if (methodMock.CallPattern.IsDerivedFromObjectEquals && method.ReflectedType.IsValueType())1055                throw new MockException("Cannot mock Equals method because JustMock depends on it. Also, when Equals is called internally by JustMock, all methods called by it will not be intercepted and will have only their original implementations called.");1056            CheckMethodInterceptorAvailable(methodMock.CallPattern.InstanceMatcher, method);1057            Type declaringType = method.DeclaringType;1058            // If we're arranging a call to a mock object, overwrite its repository.1059            // This will ensure correct behavior when a mock object is arranged1060            // in multiple contexts.1061            var refMatcher = methodMock.CallPattern.InstanceMatcher as ReferenceMatcher;1062            if (refMatcher != null)1063            {1064                var value = refMatcher.Value;1065                var mock = GetMockMixin(value, declaringType);1066                if (mock != null)1067                {1068                    methodMock.Mock = mock;1069                    mock.Repository = this;1070                }1071                if (value != null)1072                    EnableInterception(value.GetType());1073            }1074            EnableInterception(declaringType);1075            PreserveRefOutValuesBehavior.Attach(methodMock);1076            ConstructorMockBehavior.Attach(methodMock);1077            MethodInfoMatcherTreeNode funcRoot;1078            if (!arrangementTreeRoots.TryGetValue(method, out funcRoot))1079            {1080                funcRoot = new MethodInfoMatcherTreeNode(method);1081                arrangementTreeRoots.Add(method, funcRoot);1082            }1083            funcRoot.AddChild(methodMock.CallPattern, methodMock, this.sharedContext.GetNextArrangeId());1084#if !PORTABLE1085            if (ProfilerInterceptor.IsReJitEnabled)1086            {1087                CallPattern.CheckMethodCompatibility(method);1088                CallPattern.CheckInstrumentationAvailability(method);1089                ProfilerInterceptor.RequestReJit(method);1090            }1091            try1092            {1093                if (MockingContext.Plugins.Exists<IDebugWindowPlugin>())1094                {1095                    var debugWindowPlugin = MockingContext.Plugins.Get<IDebugWindowPlugin>();1096                    var argumentMatchers =1097                        methodMock.CallPattern.ArgumentMatchers1098                            .SelectMany(1099                                (IMatcher matcher, int index) =>1100                                    {1101                                        MatcherInfo[] paramsMatchers;1102                                        var matcherInfo = MatcherInfo.FromMatcherAndParamInfo(matcher, methodMock.CallPattern.Method.GetParameters()[index], out paramsMatchers);1103                                        if (matcherInfo.Kind == MatcherInfo.MatcherKind.Params && paramsMatchers.Length > 0)1104                                        {1105                                            // skip params matcher, but add all contained matchers1106                                            return paramsMatchers;1107                                        }1108                                        return new MatcherInfo[] { matcherInfo };1109                                    },1110                                (IMatcher matcher, MatcherInfo resultMatcherInfo) => resultMatcherInfo)1111                            .ToArray();1112                    debugWindowPlugin.MockCreated(1113                        methodMock.Repository.RepositoryId,1114                        methodMock.Repository.GetRepositoryPath(),1115                        MockInfo.FromMethodBase(methodMock.CallPattern.Method),1116                        argumentMatchers);1117                }1118            }1119            catch (Exception e)1120            {1121                System.Diagnostics.Trace.WriteLine("Exception thrown calling IDebugWindowPlugin plugin: " + e);1122            }1123#endif1124        }1125#if !PORTABLE1126        internal void UpdateMockDebugView(MethodBase method, IMatcher[] argumentMatchers)1127        {1128            try1129            {1130                if (MockingContext.Plugins.Exists<IDebugWindowPlugin>())1131                {1132                    var debugWindowPlugin = MockingContext.Plugins.Get<IDebugWindowPlugin>();1133                    MatcherInfo[] argumentMatcherInfos = null;1134                    if (argumentMatchers != null)1135                    {1136                        argumentMatcherInfos =1137                            argumentMatchers.Select(1138                                (IMatcher matcher, int index) =>1139                                    {1140                                        MatcherInfo[] dummy;1141                                        return MatcherInfo.FromMatcherAndParamInfo(matcher, method.GetParameters()[index], out dummy);1142                                    })1143                            .ToArray();1144                    }1145                    debugWindowPlugin.MockUpdated(1146                        this.RepositoryId,1147                        this.GetRepositoryPath(),1148                        MockInfo.FromMethodBase(method),1149                        argumentMatcherInfos);1150                }1151            }1152            catch (Exception e)1153            {1154                System.Diagnostics.Trace.WriteLine("Exception thrown calling IDebugWindowPlugin plugin: " + e);1155            }1156        }1157#endif1158        private void CheckMethodInterceptorAvailable(IMatcher instanceMatcher, MethodBase method)1159        {1160            if (ProfilerInterceptor.IsProfilerAttached)1161                return;1162            var valueMatcher = instanceMatcher as IValueMatcher;1163            if (valueMatcher == null)1164                return;1165            var instance = valueMatcher.Value;1166            if (instance == null)1167                return;1168            if (MockingProxy.CanIntercept(instance, method))1169                return;1170            if (!(instance is IMockMixin) || !method.IsInheritable())1171                ProfilerInterceptor.ThrowElevatedMockingException(method);1172        }1173#if !PORTABLE1174        private void RequestRejitForTypeMethods(Type typeToIntercept)1175        {1176            var methods = new HashSet<MethodBase>();1177            methods.UnionWith(typeToIntercept.GetMethods(MockingUtil.AllMembers));1178            methods.UnionWith(1179                typeToIntercept.GetInheritanceChain()1180                    .Where(type => type != typeToIntercept)1181                    .SelectMany(type => type.GetMethods(MockingUtil.AllMembers | BindingFlags.DeclaredOnly))1182                    .Where(method => !method.IsAbstract && method.DeclaringType != typeof(object)));1183            methods.UnionWith(1184                MockingUtil.GetAllProperties(typeToIntercept)1185                    .SelectMany(1186                        property =>1187                            {1188                                var propertyMethods = new List<MethodBase>();1189                                var getMethod = property.GetMethod;1190                                if (getMethod != null)1191                                {1192                                    propertyMethods.Add(getMethod);1193                                }1194                                var setMethod = property.SetMethod;1195                                if (setMethod != null)1196                                {1197                                    propertyMethods.Add(setMethod);1198                                }1199                                return propertyMethods;1200                            }));1201            foreach (var method in methods)1202            {1203                try1204                {1205                    CallPattern.CheckMethodCompatibility(method);1206                    CallPattern.CheckInstrumentationAvailability(method);1207                    ProfilerInterceptor.RequestReJit(method);1208                }1209                catch (MockException e)1210                {1211#if DEBUG1212                    System.Diagnostics.Trace.WriteLine(string.Format("Method {0} is skipped for interception: {1}", method, e));1213#endif1214                }1215            }1216        }1217#endif1218        internal void EnableInterception(Type typeToIntercept)1219        {1220            if (ProfilerInterceptor.IsProfilerAttached)1221            {1222                for (var type = typeToIntercept; type != null;)1223                {1224                    if (!ProfilerInterceptor.TypeSupportsInstrumentation(type))1225                        DebugView.TraceEvent(IndentLevel.Warning, () => String.Format("Elevated mocking for type {0} will not be available due to limitations in CLR", type));1226                    if (this.arrangedTypes.Add(type))1227                    {1228                        ProfilerInterceptor.EnableInterception(type, true, this);1229#if !PORTABLE1230                        if (ProfilerInterceptor.IsReJitEnabled && type == typeToIntercept)1231                        {1232                            RequestRejitForTypeMethods(type);1233                        }1234#endif1235                    }1236                    type = type.BaseType;1237                    if (type == typeof(object) || type == typeof(ValueType) || type == typeof(Enum))1238                        break;1239                }1240                using (this.sharedContext.StartRunClassConstructor())1241                {1242                    var handle = typeToIntercept.TypeHandle;1243                    this.disabledTypes.Add(typeof(RuntimeHelpers));1244                    ProfilerInterceptor.RunClassConstructor(handle);1245                    this.disabledTypes.Remove(typeof(RuntimeHelpers));1246                }1247            }1248        }1249        internal void DisableInterception(Type typeToIntercept)1250        {1251            if (ProfilerInterceptor.IsProfilerAttached)1252            {1253                if (this.arrangedTypes.Remove(typeToIntercept))1254                {1255                    ProfilerInterceptor.EnableInterception(typeToIntercept, false, this);1256                }1257                this.disabledTypes.Add(typeToIntercept);1258            }1259        }1260        private List<MethodMockMatcherTreeNode> GetMethodMocksFromObject(object mock, Type mockType = null)1261        {1262            MockingUtil.UnwrapDelegateTarget(ref mock);1263            var methodMocks = new List<MethodMockMatcherTreeNode>();1264            var visitedMocks = new List<object>(); // can't be HashSet because we can't depend on GetHashCode being implemented properly1265            GetMethodMocksFromObjectInternal(mock, mockType, methodMocks, visitedMocks);1266            return methodMocks;1267        }1268        private void GetMethodMocksFromObjectInternal(object mock, Type mockType, List<MethodMockMatcherTreeNode> methodMocks, List<object> visitedMocks)1269        {1270            if (visitedMocks.Contains(mock))1271                return;1272            visitedMocks.Add(mock);1273            IMatcher instanceMatcher;1274            Func<MethodInfoMatcherTreeNode, bool> rootMatcher;1275            if (mockType != null)1276            {1277                instanceMatcher = new AnyMatcher();1278                rootMatcher = node => mockType.IsAssignableFrom(node.MethodInfo.DeclaringType);1279            }1280            else1281            {1282                instanceMatcher = new ValueMatcher(mock);1283                rootMatcher = node =>1284                {1285                    foreach (var child in node.Children)1286                    {1287                        if (child.Matcher.Matches(instanceMatcher))1288                        {1289                            return true;1290                        }1291                    }1292                    return false;1293                };1294            }1295            foreach (var funcRoot in arrangementTreeRoots.Values.Where(rootMatcher))1296            {1297                var callPattern = CallPattern.CreateUniversalCallPattern(funcRoot.MethodInfo);1298                callPattern.InstanceMatcher = instanceMatcher;1299                var results = funcRoot.GetAllMethodMocks(callPattern);1300                methodMocks.AddRange(results);1301            }1302            if (mock != null)1303            {1304                var mockMixin = GetMockMixin(mock, null);1305                if (mockMixin != null)1306                {1307                    foreach (var dependentMock in mockMixin.DependentMocks)1308                        GetMethodMocksFromObjectInternal(dependentMock, null, methodMocks, visitedMocks);1309                }1310            }1311        }1312        private List<MethodMockMatcherTreeNode> GetAllMethodMocks()1313        {1314            var methodMocks = new List<MethodMockMatcherTreeNode>();1315            GetAllMethodMocksInternal(methodMocks);1316            return methodMocks;1317        }1318        private void GetAllMethodMocksInternal(List<MethodMockMatcherTreeNode> methodMocks)1319        {1320            foreach (var funcRoot in arrangementTreeRoots.Values)1321            {1322                var callPattern = CallPattern.CreateUniversalCallPattern(funcRoot.MethodInfo);1323                var results = funcRoot.GetAllMethodMocks(callPattern);1324                methodMocks.AddRange(results);1325            }1326        }1327        private bool DispatchInvocationToMethodMocks(Invocation invocation)1328        {1329            CallPattern callPattern = CallPatternCreator.FromInvocation(invocation);1330            MethodInfoMatcherTreeNode funcRoot = null;1331            if (!invocation.InArrange && !invocation.InAssertSet)1332            {1333                if (!invocationTreeRoots.TryGetValue(callPattern.Method, out funcRoot))1334                {1335                    funcRoot = new MethodInfoMatcherTreeNode(callPattern.Method);1336                    invocationTreeRoots.Add(callPattern.Method, funcRoot);1337                }1338            }1339            var methodMock = DispatchInvocationToArrangements(callPattern, invocation);1340            if (!invocation.InArrange && !invocation.InAssertSet)1341            {1342                funcRoot.AddOrUpdateOccurence(callPattern, methodMock);1343            }1344            return methodMock != null;1345        }1346        private IMethodMock DispatchInvocationToArrangements(CallPattern callPattern, Invocation invocation)1347        {1348            MethodInfoMatcherTreeNode arrangeFuncRoot;1349            var methodMockNodes = new List<MethodMockMatcherTreeNode>();1350            var allMethods = new[] { callPattern.Method }1351                .Concat(callPattern.Method.GetInheritanceChain().Where(m => m.DeclaringType.IsInterface));1352            foreach (var method in allMethods)1353            {1354                DebugView.TraceEvent(IndentLevel.MethodMatch, () => String.Format("Inspect arrangements on {0} on {1}", method, method.DeclaringType));1355                if (!arrangementTreeRoots.TryGetValue(method, out arrangeFuncRoot))1356                    continue;1357                var results = arrangeFuncRoot.GetMethodMock(callPattern);1358                methodMockNodes.AddRange(results);1359            }1360            var methodMock = GetMethodMockFromNodes(methodMockNodes, invocation);1361            if (methodMock == null)1362            {1363                DebugView.TraceEvent(IndentLevel.MethodMatch, () => "No arrangement chosen");1364                return null;1365            }1366            DebugView.TraceEvent(IndentLevel.MethodMatch, () => String.Format("Chosen arrangement (id={0}) {1}",1367                methodMockNodes.First(node => node.MethodMock == methodMock).Id, methodMock.ArrangementExpression));1368            methodMock.IsUsed = true; //used to correctly determine inSequence arranges1369            var behaviorsToProcess = GetBehaviorsToProcess(invocation, methodMock);1370            foreach (var behavior in behaviorsToProcess)1371            {1372                behavior.Process(invocation);1373            }1374            return methodMock;1375        }1376        private static List<IBehavior> GetBehaviorsToProcess(Invocation invocation, IMethodMock methodMock)1377        {1378            var behaviorsToExecute = new List<IBehavior>();1379            var behaviorTypesToSkip = GetBehaviorTypesToSkip(invocation);1380            behaviorsToExecute.AddRange(1381                methodMock.Behaviors.Where(behavior => !behaviorTypesToSkip.Contains(behavior.GetType())));1382            var mock = invocation.MockMixin;1383            if (mock != null)1384            {1385                behaviorsToExecute.AddRange(mock.SupplementaryBehaviors);1386#if !PORTABLE1387                // explicitly add recursive mocking behavior for ref returns in order to set invocation result1388                if (invocation.Method.GetReturnType().IsByRef)1389                {1390                    behaviorsToExecute.AddRange(1391                        mock.FallbackBehaviors.Where(1392                            behavior =>1393                                behavior is CallOriginalBehavior1394                                || (behavior is RecursiveMockingBehavior && ((RecursiveMockingBehavior)behavior).Type != RecursiveMockingBehaviorType.OnlyDuringAnalysis)));1395                }1396#endif1397            }1398            return behaviorsToExecute;1399        }1400        private static List<Type> GetBehaviorTypesToSkip(Invocation invocation)1401        {1402            var behaviorTypesToSkip = new List<Type>();1403            if (invocation.InAssertSet)1404            {1405                behaviorTypesToSkip.Add(typeof(InvocationOccurrenceBehavior));1406            }1407            return behaviorTypesToSkip;1408        }1409        private bool TryCreateDelegate(Type type, MockCreationSettings settings, out object delegateResult)1410        {1411            delegateResult = null;1412            if (!typeof(Delegate).IsAssignableFrom(type) || type == typeof(Delegate) || type == typeof(MulticastDelegate))1413                return false;1414            var backendType = mockFactory.CreateDelegateBackend(type);1415            var backend = Create(backendType, settings);1416            delegateResult = Delegate.CreateDelegate(type, backend, backendType.GetMethod("Invoke"));1417            return true;1418        }1419        private IMethodMock GetMethodMockFromNodes(List<MethodMockMatcherTreeNode> methodMockNodes, Invocation invocation)1420        {1421            if (methodMockNodes.Count == 0)1422            {1423                return null;1424            }1425            var resultList =1426                methodMockNodes1427                    .OrderBy(x => x.Id)1428                    .Select(1429                        x =>1430                            new1431                            {1432                                x.MethodMock,1433                                Acceptable = new Lazy<bool>(() => x.MethodMock.AcceptCondition == null1434                                    || (bool)x.MethodMock.AcceptCondition.CallOverride(invocation))1435                            })1436                    .ToList();1437            var isInOrderOverwrites =1438                resultList.Count() > 01439                && resultList.Where(x => x.MethodMock.IsInOrder).Any()1440                && resultList.Last().MethodMock.IsInOrder;1441            // if one or more InOrder arrangement overwrites other ones, then skip selecting others1442            if (!isInOrderOverwrites)1443            {1444                var nonSequentialOrInOrder =1445                    resultList.Where(x => !x.MethodMock.IsSequential && !x.MethodMock.IsInOrder && x.Acceptable).LastOrDefault();1446                if (nonSequentialOrInOrder != null)1447                {1448                    return nonSequentialOrInOrder.MethodMock;1449                }1450            }1451            var inOrder = resultList.Where(x => x.MethodMock.IsInOrder && !x.MethodMock.IsUsed && x.Acceptable).FirstOrDefault();1452            if (inOrder != null)1453            {1454                return inOrder.MethodMock;1455            }1456            var sequential = resultList.Where(x => x.MethodMock.IsSequential && !x.MethodMock.IsUsed && x.Acceptable).FirstOrDefault();1457            if (sequential != null)1458            {1459                return sequential.MethodMock;1460            }1461            return resultList.Where(x => (x.MethodMock.IsSequential || x.MethodMock.IsInOrder) && x.Acceptable).Select(x => x.MethodMock).LastOrDefault();1462        }1463        internal string GetDebugView(object mock = null)1464        {1465            IEnumerable<MethodMockMatcherTreeNode> nodes;1466            if (mock != null)1467            {1468                nodes = GetMethodMocksFromObject(mock);1469            }1470            else1471            {1472                nodes = from kvp in this.arrangementTreeRoots1473                        let universalCP = CallPattern.CreateUniversalCallPattern(kvp.Key)1474                        from node in kvp.Value.GetAllMethodMocks(universalCP)1475                        select node;1476            }1477            var sb = new StringBuilder();1478            sb.AppendFormat("Elevated mocking: {0}\n", ProfilerInterceptor.IsProfilerAttached ? "enabled" : "disabled");1479            sb.AppendLine("\nArrangements and expectations:");1480            bool addedStuff = false;1481            foreach (var node in nodes)1482            {1483                addedStuff = true;1484                var methodMock = node.MethodMock;1485                sb.AppendFormat("    Arrangement (id={1}) {0}:\n", methodMock.ArrangementExpression, node.Id);1486                foreach (var behavior in methodMock.Behaviors.OfType<IAssertableBehavior>())1487                {1488                    var debugView = behavior.DebugView;1489                    if (debugView != null)1490                        sb.AppendFormat("        {0}\n", debugView);1491                }1492            }...DynamicProxyInterceptor.cs
Source:DynamicProxyInterceptor.cs  
...15using Telerik.JustMock.Core.Castle.DynamicProxy;16using Telerik.JustMock.Diagnostics;17namespace Telerik.JustMock.Core18{19	internal class DynamicProxyInterceptor : IInterceptor20	{21		private readonly MocksRepository constructionRepo;22		internal DynamicProxyInterceptor(MocksRepository constructionRepo)23		{24			this.constructionRepo = constructionRepo;25		}26		public void Intercept(IInvocation invocation)27		{28			if (ProfilerInterceptor.ReentrancyCounter > 0)29			{30				CallOriginal(invocation, false);31				return;32			}33			bool callOriginal = false;34			ProfilerInterceptor.GuardInternal(() =>35			{36				var mockInvocation = new Invocation(invocation.Proxy, invocation.GetConcreteMethod(), invocation.Arguments);37				DebugView.TraceEvent(IndentLevel.Dispatch, () => String.Format("Intercepted DP call: {0}", mockInvocation.InputToString()));38				DebugView.PrintStackTrace();39				var mock = mockInvocation.MockMixin;40				var repo = mock != null ? mock.Repository : this.constructionRepo;41				lock (repo)42				{43					repo.DispatchInvocation(mockInvocation);44				}45				invocation.ReturnValue = mockInvocation.ReturnValue;46				callOriginal = mockInvocation.CallOriginal;47				if (callOriginal)48				{49					DebugView.TraceEvent(IndentLevel.DispatchResult, () => "Calling original implementation");50				}51				else if (mockInvocation.IsReturnValueSet)...Intercept
Using AI Code Generation
1using Telerik.JustMock;2using Telerik.JustMock.Core;3using System;4using System.Collections.Generic;5using System.Linq;6using System.Text;7using System.Threading.Tasks;8{9    {10        static void Main(string[] args)11        {12            var mock = Mock.Create<IFoo>();13            Mock.Arrange(() => mock.Bar()).DoInstead(() => Console.WriteLine("Bar"));14            Mock.Arrange(() => mock.Baz()).DoInstead(() => Console.WriteLine("Baz"));15            Mock.Arrange(() => mock.Qux()).DoInstead(() => Console.WriteLine("Qux"));16            Mock.Arrange(() => mock.Quux()).DoInstead(() => Console.WriteLine("Quux"));17            Mock.Arrange(() => mock.Corge()).DoInstead(() => Console.WriteLine("Corge"));18            Mock.Arrange(() => mock.Garply()).DoInstead(() => Console.WriteLine("Garply"));19            Mock.Arrange(() => mock.Foo()).DoInstead(() => Console.WriteLine("Foo"));20            Mock.Arrange(() => mock.Waldo()).DoInstead(() => Console.WriteLine("Waldo"));21            Mock.Arrange(() => mock.Fred()).DoInstead(() => Console.WriteLine("Fred"));22            Mock.Arrange(() => mock.Plugh()).DoInstead(() => Console.WriteLine("Plugh"));23            Mock.Arrange(() => mock.Xyzzy()).DoInstead(() => Console.WriteLine("Xyzzy"));24            Mock.Arrange(() => mock.Thud()).DoInstead(() => Console.WriteLine("Thud"));25            var proxy = new DynamicProxyInterceptor();26            proxy.Intercept(mock);27            mock.Bar();28            mock.Baz();29            mock.Qux();30            mock.Quux();31            mock.Corge();32            mock.Garply();33            mock.Foo();34            mock.Waldo();35            mock.Fred();36            mock.Plugh();37            mock.Xyzzy();38            mock.Thud();39            Console.ReadLine();40        }41    }42    {43        void Bar();44        void Baz();45        void Qux();46        void Quux();47        void Corge();48        void Garply();49        void Foo();50        void Waldo();51        void Fred();52        void Plugh();53        void Xyzzy();54        void Thud();55    }56}Intercept
Using AI Code Generation
1using Telerik.JustMock;2using Telerik.JustMock.Core;3{4    public string Method1()5    {6        return "Hello";7    }8}9{10    public string Method2(Class1 c)11    {12        return c.Method1();13    }14}15public void Method1_ShouldReturnHello()16{17    var c = Mock.Create<Class1>();18    Mock.Arrange(() => c.Method1()).DoInstead(() => "Hello");19    var c2 = new Class2();20    var result = c2.Method2(c);21    Assert.AreEqual("Hello", result);22}23using Telerik.JustMock;24using Telerik.JustMock.Core;25{26    public string Method1()27    {28        return "Hello";29    }30}31{32    public string Method2(Class1 c)33    {34        return c.Method1();35    }36}37public void Method1_ShouldReturnHello()38{39    var c = Mock.Create<Class1>();40    Mock.Arrange(() => c.Method1()).DoInstead(() => "Hello");41    var c2 = new Class2();42    var result = c2.Method2(c);43    Assert.AreEqual("Hello", result);44}45using Telerik.JustMock;46using Telerik.JustMock.Core;47{48    public string Method1()49    {50        return "Hello";51    }52}53{54    public string Method2(Class1 c)55    {56        return c.Method1();57    }58}59public void Method1_ShouldReturnHello()60{61    var c = Mock.Create<Class1>();62    Mock.Arrange(() => c.Method1()).DoInstead(() => "Hello");63    var c2 = new Class2();64    var result = c2.Method2(c);65    Assert.AreEqual("Hello", result);66}67using Telerik.JustMock;68using Telerik.JustMock.Core;69{70    public string Method1()71    {72        return "Hello";73    }74}Intercept
Using AI Code Generation
1{2    public void Method1()3    {4        Console.WriteLine("Method1");5    }6}7using Telerik.JustMock.Core;8using Telerik.JustMock;9using System;10using System.Collections.Generic;11using System.Linq;12using System.Text;13using System.Threading.Tasks;14{15    {16        static void Main(string[] args)17        {18            var obj = Mock.Create<Class1>();19            Mock.Arrange(() => obj.Method1());20            DynamicProxyInterceptor.Intercept(obj, "Method1", new object[] { });21        }22    }23}24public static void Method1()25{26Console.WriteLine("Method1");27}28var obj = Mock.Create<Class1>();29Mock.Arrange(() => Class1.Method1());30DynamicProxyInterceptor.Intercept(obj, "Method1", new object[] { });31{32    public static void Method1()33    {34        Console.WriteLine("Method1");35    }36}37using Telerik.JustMock.Core;38using Telerik.JustMock;39using System;40using System.Collections.Generic;41using System.Linq;42using System.Text;43using System.Threading.Tasks;44{45    {46        static void Main(string[] args)47        {48            Mock.ArrangeStatic(() => Class1Intercept
Using AI Code Generation
1{2    public void Method1()3    {4        var interceptor = new Telerik.JustMock.Core.DynamicProxyInterceptor();5        var instance = Telerik.JustMock.Mock.Create<Interface1>(interceptor);6        var proxy = Telerik.JustMock.Mock.GetMock(instance);7        Telerik.JustMock.Mock.Arrange(() => proxy.Method1()).Intercept(() => { Console.WriteLine("Hello World!"); });8        instance.Method1();9    }10}11{12    public void Method2()13    {14        var interceptor = new Telerik.JustMock.Core.DynamicProxyInterceptor();15        var instance = Telerik.JustMock.Mock.Create<Interface1>(interceptor);16        var proxy = Telerik.JustMock.Mock.GetMock(instance);17        Telerik.JustMock.Mock.Arrange(() => proxy.Method1()).Intercept(() => { Console.WriteLine("Hello World!"); });18        instance.Method1();19    }20}21{22    public void Method3()23    {24        var interceptor = new Telerik.JustMock.Core.DynamicProxyInterceptor();25        var instance = Telerik.JustMock.Mock.Create<Interface1>(interceptor);26        var proxy = Telerik.JustMock.Mock.GetMock(instance);27        Telerik.JustMock.Mock.Arrange(() => proxy.Method1()).Intercept(() => { Console.WriteLine("Hello World!"); });28        instance.Method1();29    }30}31{32    public void Method4()33    {34        var interceptor = new Telerik.JustMock.Core.DynamicProxyInterceptor();35        var instance = Telerik.JustMock.Mock.Create<Interface1>(interceptor);36        var proxy = Telerik.JustMock.Mock.GetMock(instance);37        Telerik.JustMock.Mock.Arrange(() => proxy.Method1()).Intercept(() => { Console.WriteLine("Hello World!"); });38        instance.Method1();39    }40}41{42    public void Method5()43    {44        var interceptor = new Telerik.JustMock.Core.DynamicProxyInterceptor();Intercept
Using AI Code Generation
1public void TestMethod1()2{3    var mock = Mock.Create<TestClass>();4    Mock.Arrange(() => mock.Method())5        .DoInstead(() => Console.WriteLine("Do something before the method call"))6        .Intercept()7        .DoInstead(() => Console.WriteLine("Do something after the method call"))8        .MustBeCalled();9    mock.Method();10    Mock.Assert(mock);11}12public void TestMethod2()13{14    var mock = Mock.Create<TestClass>();15    Mock.Arrange(() => mock.Method())16        .DoInstead(() => Console.WriteLine("Do something before the method call"))17        .Intercept()18        .DoInstead(() => Console.WriteLine("Do something after the method call"))19        .MustBeCalled();20    mock.Method();21    Mock.Assert(mock);22}23public void TestMethod3()24{25    var mock = Mock.Create<TestClass>();26    Mock.Arrange(() => mock.Method())27        .DoInstead(() => Console.WriteLine("Do something before the method call"))28        .Intercept()29        .DoInstead(() => Console.WriteLine("Do something after the method call"))30        .MustBeCalled();31    mock.Method();32    Mock.Assert(mock);33}34public void TestMethod4()35{36    var mock = Mock.Create<TestClass>();37    Mock.Arrange(() => mock.Method())38        .DoInstead(() => Console.WriteLine("Do something before the method call"))39        .Intercept()40        .DoInstead(() => Console.WriteLine("Do something after the method call"))41        .MustBeCalled();42    mock.Method();43    Mock.Assert(mock);44}45public void TestMethod5()46{47    var mock = Mock.Create<TestClass>();48    Mock.Arrange(() => mock.Method())49        .DoInstead(() => Console.WriteLine("Do something before the method call"))50        .Intercept()51        .DoInstead(() => Console.WriteLine("Do something after the method call"))52        .MustBeCalled();Intercept
Using AI Code Generation
1public void Intercept(InterceptionArgs args)2{3    Console.WriteLine("Intercepted");4    args.Proceed();5}6public void Intercept(InterceptionArgs args)7{8    Console.WriteLine("Intercepted");9    args.Proceed();10}11public void Intercept(InterceptionArgs args)12{13    Console.WriteLine("Intercepted");14    args.Proceed();15}16public void Intercept(InterceptionArgs args)17{18    Console.WriteLine("Intercepted");19    args.Proceed();20}21public void Intercept(InterceptionArgs args)22{23    Console.WriteLine("Intercepted");24    args.Proceed();25}26public void Intercept(InterceptionArgs args)27{28    Console.WriteLine("Intercepted");29    args.Proceed();30}31public void Intercept(InterceptionArgs args)32{33    Console.WriteLine("Intercepted");34    args.Proceed();35}36public void Intercept(InterceptionArgs args)37{38    Console.WriteLine("Intercepted");39    args.Proceed();40}41public void Intercept(InterceptionArgs args)42{43    Console.WriteLine("Intercepted");44    args.Proceed();45}46public void Intercept(InterceptionArgs args)47{48    Console.WriteLine("Intercepted");49    args.Proceed();50}51public void Intercept(InterceptionArgs args)52{53    Console.WriteLine("Intercepted");54    args.Proceed();55}Intercept
Using AI Code Generation
1public void TestMethod1()2{3    var mock = Mock.Create<IContract>();4    Mock.Arrange(() => mock.Method1(1, 2)).Returns(3);5    Mock.Arrange(() => mock.Method2(1, 2)).Returns(3);6    var proxy = Mock.Create<IContract>(Behavior.CallOriginal, new DynamicProxyInterceptor(mock));7    Assert.AreEqual(3, proxy.Method1(1, 2));8    Assert.AreEqual(3, proxy.Method2(1, 2));9}10public void TestMethod1()11{12    var mock = Mock.Create<IContract>();13    Mock.Arrange(() => mock.Method1(1, 2)).Returns(3);14    Mock.Arrange(() => mock.Method2(1, 2)).Returns(3);15    var proxy = Mock.Create<IContract>(Behavior.CallOriginal, new DynamicProxyInterceptor(mock));16    Assert.AreEqual(3, proxy.Method1(1, 2));17    Assert.AreEqual(3, proxy.Method2(1, 2));18}19public void TestMethod1()20{21    var mock = Mock.Create<IContract>();22    Mock.Arrange(() => mock.Method1(1, 2)).Returns(3);23    Mock.Arrange(() => mock.Method2(1, 2)).Returns(3);24    var proxy = Mock.Create<IContract>(Behavior.CallOriginal, new DynamicProxyInterceptor(mock));25    Assert.AreEqual(3, proxy.Method1(1, 2));26    Assert.AreEqual(3, proxy.Method2(1, 2));27}28public void TestMethod1()29{30    var mock = Mock.Create<IContract>();31    Mock.Arrange(() => mock.Method1(1, 2)).Returns(3);32    Mock.Arrange(() => mock.Method2(1, 2)).Returns(3);Intercept
Using AI Code Generation
1using System;2using System.Reflection;3using Telerik.JustMock;4{5    {6        public virtual string Method1(string var1, int var2)7        {8            return "Method1";9        }10    }11    {12        public string Method2()13        {14            Class1 obj = new Class1();15            return obj.Method1("Test", 1);16        }17    }18    {19        public void TestMethod1()20        {21            var obj = Mock.Create<Class2>();22            Mock.Arrange(() => obj.Method2()).Returns("Test");23            string result = obj.Method2();24            Assert.AreEqual("Test", result);25        }26    }27}28using System;29using System.Reflection;30using Telerik.JustMock;31{32    {33        public virtual string Method1(string var1, int var2)34        {35            return "Method1";36        }37    }38    {39        public string Method2()40        {41            Class1 obj = new Class1();42            return obj.Method1("Test", 1);43        }Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
