public InterceptionAction HandleIntercept(ICallContext invocation, InterceptorContext ctx, CurrentInterceptContext localctx) { this.ctx = ctx; if (!FluentMockContext.IsActive) { //Special case for events if (invocation.Method.IsEventAttach()) { var delegateInstance = (Delegate)invocation.Arguments[0]; // TODO: validate we can get the event? var eventInfo = this.GetEventFromName(invocation.Method.Name.Substring(4)); if (ctx.Mock.CallBase && !eventInfo.DeclaringType.IsInterface) { invocation.InvokeBase(); } else if (delegateInstance != null) { ctx.AddEventHandler(eventInfo, (Delegate)invocation.Arguments[0]); } return(InterceptionAction.Stop); } else if (invocation.Method.IsEventDetach()) { var delegateInstance = (Delegate)invocation.Arguments[0]; // TODO: validate we can get the event? var eventInfo = this.GetEventFromName(invocation.Method.Name.Substring(7)); if (ctx.Mock.CallBase && !eventInfo.DeclaringType.IsInterface) { invocation.InvokeBase(); } else if (delegateInstance != null) { ctx.RemoveEventHandler(eventInfo, (Delegate)invocation.Arguments[0]); } return(InterceptionAction.Stop); } // Save to support Verify[expression] pattern. // In a fluent invocation context, which is a recorder-like // mode we use to evaluate delegates by actually running them, // we don't want to count the invocation, or actually run // previous setups. ctx.AddInvocation(invocation); } return(InterceptionAction.Continue); }
public InterceptionAction HandleIntercept(ICallContext invocation, InterceptorContext ctx, CurrentInterceptContext localctx) { this.ctx = ctx; if (!FluentMockContext.IsActive) { //Special case for events if (invocation.Method.IsEventAttach()) { var delegateInstance = (Delegate)invocation.Arguments[0]; // TODO: validate we can get the event? var eventInfo = this.GetEventFromName(invocation.Method.Name.Substring(4)); if (ctx.Mock.CallBase && !eventInfo.DeclaringType.IsInterface) { invocation.InvokeBase(); } else if (delegateInstance != null) { ctx.AddEventHandler(eventInfo, (Delegate)invocation.Arguments[0]); } return InterceptionAction.Stop; } else if (invocation.Method.IsEventDetach()) { var delegateInstance = (Delegate)invocation.Arguments[0]; // TODO: validate we can get the event? var eventInfo = this.GetEventFromName(invocation.Method.Name.Substring(7)); if (ctx.Mock.CallBase && !eventInfo.DeclaringType.IsInterface) { invocation.InvokeBase(); } else if (delegateInstance != null) { ctx.RemoveEventHandler(eventInfo, (Delegate)invocation.Arguments[0]); } return InterceptionAction.Stop; } // Save to support Verify[expression] pattern. // In a fluent invocation context, which is a recorder-like // mode we use to evaluate delegates by actually running them, // we don't want to count the invocation, or actually run // previous setups. ctx.AddInvocation(invocation); } return InterceptionAction.Continue; }
public override void Execute(ICallContext call) { base.Execute(call); if (this.returnValueKind == ReturnValueKind.CallBase) { call.InvokeBase(); } else { call.ReturnValue = this.valueDel.HasCompatibleParameterList(new ParameterInfo[0]) ? valueDel.InvokePreserveStack() //we need this, for the user to be able to use parameterless methods : valueDel.InvokePreserveStack(call.Arguments); //will throw if parameters mismatch } this.afterReturnCallback?.Invoke(call.Arguments); }
public InterceptionAction HandleIntercept(ICallContext invocation, InterceptorContext ctx, CurrentInterceptContext localctx) { if (invocation.Method.DeclaringType == typeof(object) || invocation.Method.DeclaringType.IsClass && !invocation.Method.IsAbstract && ctx.Mock.CallBase ) { // Invoke underlying implementation. // For mocked classes, if the target method was not abstract, // invoke directly. // Will only get here for Loose behavior. // TODO: we may want to provide a way to skip this by the user. invocation.InvokeBase(); return(InterceptionAction.Stop); } else { return(InterceptionAction.Continue); } }
public InterceptionAction HandleIntercept(ICallContext invocation, InterceptStrategyContext ctx) { if (invocation.Method.DeclaringType == typeof(object) || invocation.Method.DeclaringType.IsClass && !invocation.Method.IsAbstract && ctx.Mock.CallBase ) { // Invoke underlying implementation. // For mocked classes, if the target method was not abstract, // invoke directly. // Will only get here for Loose behavior. // TODO: we may want to provide a way to skip this by the user. invocation.InvokeBase(); return InterceptionAction.Stop; } else { return InterceptionAction.Continue; } }
public InterceptionAction HandleIntercept(ICallContext invocation, InterceptorContext ctx, CurrentInterceptContext localctx) { if (invocation.Method.DeclaringType == typeof(object) || // interface proxy ctx.Mock.ImplementedInterfaces.Contains(invocation.Method.DeclaringType) && !invocation.Method.IsEventAttach() && !invocation.Method.IsEventDetach() && ctx.Mock.CallBase && !ctx.Mock.MockedType.IsInterface || // class proxy with explicitly implemented interfaces. The method's declaring type is the interface and the method couldn't be abstract invocation.Method.DeclaringType.IsClass && !invocation.Method.IsAbstract && ctx.Mock.CallBase // class proxy ) { // Invoke underlying implementation. // For mocked classes, if the target method was not abstract, // invoke directly. // Will only get here for Loose behavior. // TODO: we may want to provide a way to skip this by the user. invocation.InvokeBase(); return(InterceptionAction.Stop); } else { return(InterceptionAction.Continue); } }
public InterceptionAction HandleIntercept(ICallContext invocation, InterceptorContext ctx, CurrentInterceptContext localctx) { if (invocation.Method.DeclaringType == typeof(object) || // interface proxy ctx.Mock.ImplementedInterfaces.Contains(invocation.Method.DeclaringType) && !invocation.Method.IsEventAttach() && !invocation.Method.IsEventDetach() && ctx.Mock.CallBase || // class proxy with explicitly implemented interfaces. The method's declaring type is the interface and the method couldn't be abstract invocation.Method.DeclaringType.IsClass && !invocation.Method.IsAbstract && ctx.Mock.CallBase // class proxy ) { // Invoke underlying implementation. // For mocked classes, if the target method was not abstract, // invoke directly. // Will only get here for Loose behavior. // TODO: we may want to provide a way to skip this by the user. invocation.InvokeBase(); return InterceptionAction.Stop; } else { return InterceptionAction.Continue; } }
public void Intercept(ICallContext invocation) { if (invocation.Method.IsDestructor()) { return; } // Track current invocation if we're in "record" mode in a fluent invocation context. if (FluentMockContext.IsActive) { FluentMockContext.Current.Add(this.Mock, invocation); } // TODO: too many ifs in this method. // see how to refactor with strategies. if (invocation.Method.DeclaringType.IsGenericType() && invocation.Method.DeclaringType.GetGenericTypeDefinition() == typeof(IMocked <>)) { // "Mixin" of IMocked<T>.Mock invocation.ReturnValue = this.Mock; return; } else if (invocation.Method.DeclaringType == typeof(IMocked)) { // "Mixin" of IMocked.Mock invocation.ReturnValue = this.Mock; return; } // Special case for events. if (!FluentMockContext.IsActive) { if (invocation.Method.IsEventAttach()) { var delegateInstance = (Delegate)invocation.Arguments[0]; // TODO: validate we can get the event? var eventInfo = this.GetEventFromName(invocation.Method.Name.Substring(4)); if (this.Mock.CallBase) { invocation.InvokeBase(); } else if (delegateInstance != null) { this.AddEventHandler(eventInfo, (Delegate)invocation.Arguments[0]); } return; } else if (invocation.Method.IsEventDetach()) { var delegateInstance = (Delegate)invocation.Arguments[0]; // TODO: validate we can get the event? var eventInfo = this.GetEventFromName(invocation.Method.Name.Substring(7)); if (this.Mock.CallBase) { invocation.InvokeBase(); } else if (delegateInstance != null) { this.RemoveEventHandler(eventInfo, (Delegate)invocation.Arguments[0]); } return; } // Save to support Verify[expression] pattern. // In a fluent invocation context, which is a recorder-like // mode we use to evaluate delegates by actually running them, // we don't want to count the invocation, or actually run // previous setups. actualInvocations.Add(invocation); } var call = FluentMockContext.IsActive ? (IProxyCall)null : orderedCalls.LastOrDefault(c => c.Matches(invocation)); if (call == null && !FluentMockContext.IsActive && behavior == MockBehavior.Strict) { throw new MockException(MockException.ExceptionReason.NoSetup, behavior, invocation); } if (call != null) { call.SetOutParameters(invocation); // We first execute, as there may be a Throws // and therefore we might never get to the // next line. call.Execute(invocation); ThrowIfReturnValueRequired(call, invocation); } else if (invocation.Method.DeclaringType == typeof(object)) { // Invoke underlying implementation. invocation.InvokeBase(); } else if (invocation.Method.DeclaringType.IsClass() && !invocation.Method.IsAbstract && this.Mock.CallBase) { // For mocked classes, if the target method was not abstract, // invoke directly. // Will only get here for Loose behavior. // TODO: we may want to provide a way to skip this by the user. invocation.InvokeBase(); } else if (invocation.Method != null && invocation.Method.ReturnType != null && invocation.Method.ReturnType != typeof(void)) { Mock recursiveMock; if (this.Mock.InnerMocks.TryGetValue(invocation.Method, out recursiveMock)) { invocation.ReturnValue = recursiveMock.Object; } else { invocation.ReturnValue = this.Mock.DefaultValueProvider.ProvideDefault(invocation.Method); } } }
public void Intercept(ICallContext invocation) { if (invocation.Method.IsDestructor()) { return; } // Track current invocation if we're in "record" mode in a fluent invocation context. if (FluentMockContext.IsActive) { FluentMockContext.Current.Add(this.Mock, invocation); } // TODO: too many ifs in this method. // see how to refactor with strategies. if (invocation.Method.DeclaringType.IsGenericType() && invocation.Method.DeclaringType.GetGenericTypeDefinition() == typeof(IMocked<>)) { // "Mixin" of IMocked<T>.Mock invocation.ReturnValue = this.Mock; return; } else if (invocation.Method.DeclaringType == typeof(IMocked)) { // "Mixin" of IMocked.Mock invocation.ReturnValue = this.Mock; return; } // Special case for events. if (!FluentMockContext.IsActive) { if (invocation.Method.IsEventAttach()) { var delegateInstance = (Delegate)invocation.Arguments[0]; // TODO: validate we can get the event? var eventInfo = this.GetEventFromName(invocation.Method.Name.Substring(4)); if (this.Mock.CallBase) { invocation.InvokeBase(); } else if (delegateInstance != null) { this.AddEventHandler(eventInfo, (Delegate)invocation.Arguments[0]); } return; } else if (invocation.Method.IsEventDetach()) { var delegateInstance = (Delegate)invocation.Arguments[0]; // TODO: validate we can get the event? var eventInfo = this.GetEventFromName(invocation.Method.Name.Substring(7)); if (this.Mock.CallBase) { invocation.InvokeBase(); } else if (delegateInstance != null) { this.RemoveEventHandler(eventInfo, (Delegate)invocation.Arguments[0]); } return; } // Save to support Verify[expression] pattern. // In a fluent invocation context, which is a recorder-like // mode we use to evaluate delegates by actually running them, // we don't want to count the invocation, or actually run // previous setups. actualInvocations.Add(invocation); } var call = FluentMockContext.IsActive ? (IProxyCall)null : orderedCalls.LastOrDefault(c => c.Matches(invocation)); if (call == null && !FluentMockContext.IsActive && behavior == MockBehavior.Strict) { throw new MockException(MockException.ExceptionReason.NoSetup, behavior, invocation); } if (call != null) { call.SetOutParameters(invocation); // We first execute, as there may be a Throws // and therefore we might never get to the // next line. call.Execute(invocation); ThrowIfReturnValueRequired(call, invocation); } else if (invocation.Method.DeclaringType == typeof(object)) { // Invoke underlying implementation. invocation.InvokeBase(); } else if (invocation.Method.DeclaringType.IsClass() && !invocation.Method.IsAbstract && this.Mock.CallBase) { // For mocked classes, if the target method was not abstract, // invoke directly. // Will only get here for Loose behavior. // TODO: we may want to provide a way to skip this by the user. invocation.InvokeBase(); } else if (invocation.Method != null && invocation.Method.ReturnType != null && invocation.Method.ReturnType != typeof(void)) { Mock recursiveMock; if (this.Mock.InnerMocks.TryGetValue(invocation.Method, out recursiveMock)) { invocation.ReturnValue = recursiveMock.Object; } else { invocation.ReturnValue = this.Mock.DefaultValueProvider.ProvideDefault(invocation.Method); } } }
public InterceptionAction HandleIntercept(ICallContext invocation, InterceptorContext ctx, CurrentInterceptContext localctx) { this.ctx = ctx; if (!FluentMockContext.IsActive) { //Special case for events if (invocation.Method.LooksLikeEventAttach()) { var eventInfo = this.GetEventFromName(invocation.Method.Name.Substring("add_".Length)); if (eventInfo != null) { // TODO: We could compare `invocation.Method` and `eventInfo.GetAddMethod()` here. // If they are equal, then `invocation.Method` is definitely an event `add` accessor. // Not sure whether this would work with F# and COM; see commit 44070a9. if (ctx.Mock.CallBase && !invocation.Method.IsAbstract) { invocation.InvokeBase(); return(InterceptionAction.Stop); } else if (invocation.Arguments.Length > 0 && invocation.Arguments[0] is Delegate delegateInstance) { ctx.AddEventHandler(eventInfo, delegateInstance); return(InterceptionAction.Stop); } } // wasn't an event attach accessor after all return(InterceptionAction.Continue); } else if (invocation.Method.LooksLikeEventDetach()) { var eventInfo = this.GetEventFromName(invocation.Method.Name.Substring("remove_".Length)); if (eventInfo != null) { // TODO: We could compare `invocation.Method` and `eventInfo.GetRemoveMethod()` here. // If they are equal, then `invocation.Method` is definitely an event `remove` accessor. // Not sure whether this would work with F# and COM; see commit 44070a9. if (ctx.Mock.CallBase && !invocation.Method.IsAbstract) { invocation.InvokeBase(); return(InterceptionAction.Stop); } else if (invocation.Arguments.Length > 0 && invocation.Arguments[0] is Delegate delegateInstance) { ctx.RemoveEventHandler(eventInfo, delegateInstance); return(InterceptionAction.Stop); } } // wasn't an event detach accessor after all return(InterceptionAction.Continue); } // Save to support Verify[expression] pattern. // In a fluent invocation context, which is a recorder-like // mode we use to evaluate delegates by actually running them, // we don't want to count the invocation, or actually run // previous setups. ctx.AddInvocation(invocation); } return(InterceptionAction.Continue); }