public static bool Handle(Invocation invocation, Mock mock) { const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly; var methodName = invocation.Method.Name; // Special case for event accessors. The following, seemingly random character checks are guards against // more expensive checks (for the common case where the invoked method is *not* an event accessor). if (methodName.Length > 4) { if (methodName[0] == 'a' && methodName[3] == '_' && invocation.Method.IsEventAddAccessor()) { var implementingMethod = invocation.Method.GetImplementingMethod(invocation.ProxyType); var @event = implementingMethod.DeclaringType.GetEvents(bindingFlags).SingleOrDefault(e => e.GetAddMethod(true) == implementingMethod); if (@event != null) { bool doesntHaveEventSetup = !mock.MutableSetups.HasEventSetup; if (mock.CallBase && !invocation.Method.IsAbstract) { if (doesntHaveEventSetup) { invocation.ReturnValue = invocation.CallBase(); } } else if (invocation.Arguments.Length > 0 && invocation.Arguments[0] is Delegate delegateInstance) { mock.EventHandlers.Add(@event, delegateInstance); } return(doesntHaveEventSetup); } } else if (methodName[0] == 'r' && methodName.Length > 7 && methodName[6] == '_' && invocation.Method.IsEventRemoveAccessor()) { var implementingMethod = invocation.Method.GetImplementingMethod(invocation.ProxyType); var @event = implementingMethod.DeclaringType.GetEvents(bindingFlags).SingleOrDefault(e => e.GetRemoveMethod(true) == implementingMethod); if (@event != null) { bool doesntHaveEventSetup = !mock.MutableSetups.HasEventSetup; if (mock.CallBase && !invocation.Method.IsAbstract) { if (doesntHaveEventSetup) { invocation.ReturnValue = invocation.CallBase(); } } else if (invocation.Arguments.Length > 0 && invocation.Arguments[0] is Delegate delegateInstance) { mock.EventHandlers.Remove(@event, delegateInstance); } return(doesntHaveEventSetup); } } } return(false); }