/// <summary> /// Increments actual call counter /// </summary> /// <param name="item"></param> public void AddActualCall(Actuals item) { actuals.Add(item); }
/// <summary> /// Indicates whether this expectation handled the actual method call /// </summary> /// <param name="item"></param> /// <returns></returns> public bool HandledActual(Actuals item) { return(actuals.Any(x => x.HashCode == item.HashCode)); }
/// <summary> /// Indicates whether this expectation handled the actual method call /// </summary> /// <param name="item"></param> /// <returns></returns> public bool HandledActual(Actuals item) { return actuals.Any(x => x.HashCode == item.HashCode); }
/// <summary> /// Handles a property call /// </summary> /// <param name="invocation"></param> /// <param name="method"></param> /// <param name="arguments"></param> /// <returns></returns> public object HandlePropertyCall(IInvocation invocation, MethodInfo method, object[] arguments) { var actual = new Actuals(method, arguments); actuals.Add(actual); var methodName = method.Name; var propertyKey = GeneratePropertyKey(method, arguments); var propertyCollection = container .Where(x => x.Type == ExpectationType.Property) .ToArray(); Expectation expectation = null; for (int entryIndex = 0; entryIndex < propertyCollection.Length; entryIndex++) { var entry = propertyCollection[entryIndex]; if (!entry.MatchesCall(method, arguments)) continue; if (entry.ExpectationSatisfied) continue; expectation = entry; break; } //NOTE: this could be where a "strict" mock call would throw an exception if (expectation == null) RhinoMocks.Logger.LogUnexpectedMethodCall(invocation, "Property: Dynamic handling of property."); else { RhinoMocks.Logger.LogExpectedMethodCall(invocation); expectation.AddActualCall(actual); if (expectation.ThrowsException) throw expectation.ExceptionToThrow; if (expectation.ForceProceed) { invocation.Proceed(); return invocation.ReturnValue; } if (methodName.StartsWith("get_", StringComparison.Ordinal)) { if (expectation.HasReturnValue) return expectation.ReturnValue; } } if (methodName.StartsWith("get_", StringComparison.Ordinal)) { if (dynamicProperties.ContainsKey(propertyKey)) return dynamicProperties[propertyKey]; } if (methodName.StartsWith("set_", StringComparison.Ordinal)) { if (expectation != null && expectation.HasReturnValue) dynamicProperties[propertyKey] = expectation.ReturnValue; else dynamicProperties[propertyKey] = arguments.Last(); } return null; }
/// <summary> /// /// </summary> /// <param name="invocation"></param> /// <param name="method"></param> /// <param name="arguments"></param> /// <returns></returns> public object HandleEventCall(IInvocation invocation, MethodInfo method, object[] arguments) { var actual = new Actuals(method, arguments); actuals.Add(actual); var subscription = (Delegate)arguments[0]; HandleEventSubscription(method, subscription); var eventCollection = container .Where(x => x.Type == ExpectationType.Event) .ToArray(); Expectation expectation = null; for (int entryIndex = 0; entryIndex < eventCollection.Length; entryIndex++) { var entry = eventCollection[entryIndex]; if (!entry.MatchesCall(method, arguments)) continue; if (entry.ExpectationSatisfied) continue; expectation = entry; break; } //NOTE: this could be where a "strict" mock call would throw an exception if (expectation == null) return HandleUnexpectedMethodCall(invocation, method, arguments); RhinoMocks.Logger.LogExpectedMethodCall(invocation); expectation.AddActualCall(actual); if (expectation.ThrowsException) throw expectation.ExceptionToThrow; if (expectation.ForceProceed) { invocation.Proceed(); return invocation.ReturnValue; } return expectation.ReturnValue; }
/// <summary> /// Handle a method call for the underlying mocked object /// </summary> /// <param name="invocation"></param> /// <param name="method"></param> /// <param name="arguments"></param> /// <returns></returns> public object HandleMethodCall(IInvocation invocation, MethodInfo method, object[] arguments) { if (arguments == null) arguments = new object[0]; if (method.IsSpecialName) { var methodName = method.Name; if (methodName.StartsWith("get_", StringComparison.Ordinal) || methodName.StartsWith("set_", StringComparison.Ordinal)) { if (container.Any(x => x.Type == ExpectationType.Property)) return HandlePropertyCall(invocation, method, arguments); } if (methodName.StartsWith("add_", StringComparison.Ordinal) || methodName.StartsWith("remove_", StringComparison.Ordinal)) { if (container.Any(x => x.Type == ExpectationType.Event)) return HandleEventCall(invocation, method, arguments); } } var actual = new Actuals(method, arguments); actuals.Add(actual); var methodCollection = container .Where(x => x.Type == ExpectationType.Method) .ToArray(); Expectation expectation = null; for (int entryIndex = 0; entryIndex < methodCollection.Length; entryIndex++) { var entry = methodCollection[entryIndex]; if (!entry.MatchesCall(method, arguments)) continue; if (entry.ExpectationSatisfied) continue; expectation = entry; break; } //NOTE: this could be where a "strict" mock call would throw an exception if (expectation == null) { for (int entryIndex = 0; entryIndex < methodCollection.Length; entryIndex++) { var entry = methodCollection[entryIndex]; if (!entry.MatchesCall(method, arguments)) continue; if (entry.ExpectationSatisfied) { entry.AddActualCall(actual); continue; } } return HandleUnexpectedMethodCall(invocation, method, arguments); } RhinoMocks.Logger.LogExpectedMethodCall(invocation); expectation.AddActualCall(actual); if (expectation.HasDelegateToInvoke) { var methodParameters = method.GetParameters(); var callback = expectation.DelegateToInvoke; var callbackParameters = callback.Method.GetParameters(); try { if (callbackParameters.Length == 0) { var value = callback.DynamicInvoke(new object[0]); if (callback.Method.ReturnType != (typeof(void)) && expectation.DelegateReturnsValue) expectation.SetReturnValue(value); } else { var invokeCallback = true; var invokeArguments = new object[callbackParameters.Length]; for (int index = 0; index < callbackParameters.Length; index++) { var parameter = callbackParameters[index]; var parameterType = parameter.ParameterType; var argument = methodParameters[index]; var argumentType = argument.ParameterType; if (!parameterType.IsAssignableFrom(argumentType)) { invokeCallback = false; break; } } if (invokeCallback) { var value = callback.DynamicInvoke(arguments); if (callback.Method.ReturnType != (typeof(void)) && expectation.DelegateReturnsValue) expectation.SetReturnValue(value); } } } catch (TargetInvocationException ex) { throw ex.InnerException; } } if (expectation.ReturnArguments != null && expectation.ReturnArguments.Any()) { var lenth = expectation.ReturnArguments.Length; var parameters = method.GetParameters(); for (int index = 0, returnIndex = 0; index < parameters.Length && returnIndex < lenth; index++) { var parameter = parameters[index]; if (!parameter.IsOut && !parameter.ParameterType.IsByRef) continue; arguments[index] = expectation.ReturnArguments[returnIndex]; returnIndex++; } } if (expectation.ThrowsException) throw expectation.ExceptionToThrow; if (expectation.ForceProceed) { invocation.Proceed(); if (expectation.HasDelegateToIntercept) expectation.DelegateToIntercept(new MethodInvocation(invocation)); return invocation.ReturnValue; } invocation.ReturnValue = expectation.ReturnValue; if (expectation.HasDelegateToIntercept) expectation.DelegateToIntercept(new MethodInvocation(invocation)); return invocation.ReturnValue; }