/// <summary> /// This will be called before the actual assert method. Executes all methods in the context marked with the <see cref="PrerequisiteAttribute"/>. /// </summary> protected void RunPrerequisites() { var prerequisiteTestsToRun = TypeInvestigationService.GetPrerequisiteTestMethods(this.contextType); foreach (var prerequisiteTest in prerequisiteTestsToRun) { try { prerequisiteTest.Invoke(this, BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.NonPublic, null, null, CultureInfo.InvariantCulture); } catch (TargetInvocationException ex) { var exception = ex.InnerException; if (exception is AssertionException && exception.Message.TrimStart().StartsWith("Expected")) { var message = string.Format("{0}.{1}\r\n{2}", this.contextType.Name, prerequisiteTest.Name, exception.Message); exception = new PrerequisiteFailureException(message); throw exception; } throw ExceptionEnlightenment.PrepareForRethrow(exception); } } }
/// <summary> /// Sets a private field. /// </summary> /// <param name="target"> The target object. </param> /// <param name="fieldName"> The name of the field to set. </param> /// <param name="newValue"> The new value for the field. </param> public static void SetPrivateField(object target, string fieldName, object newValue) { try { const BindingFlags BindingFlags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField; var type = target.GetType(); var fieldInfo = type.GetField(fieldName, BindingFlags); if (fieldInfo == null) { throw new ArgumentException(string.Format(@"Field with name '{0}' not found on {1}", fieldName, type.Name), @"fieldName"); } fieldInfo.SetValue(target, newValue, BindingFlags, null, CultureInfo.InvariantCulture); } catch (TargetInvocationException exception) { throw ExceptionEnlightenment.PrepareForRethrow(exception.InnerException); } }
/// <summary> /// Sets a private property. /// </summary> /// <param name="target"> The target object. </param> /// <param name="propertyName"> The name of the property to set. </param> /// <param name="newValue"> The new value for the property. </param> /// <exception cref="Exception">An exception, in case the property setter throws one.</exception> public static void SetPrivateProperty(object target, string propertyName, object newValue) { try { var type = target.GetType(); var propertyInfo = type.GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance); if (propertyInfo == null) { throw new ArgumentException(string.Format(@"Property with name '{0}' not found on {1}", propertyName, type.Name), @"propertyName"); } // If the property does not belong directly to type, fetch again the property from the declaring type (otherwise we won't have the permission to set it). if (propertyInfo.DeclaringType != null && propertyInfo.DeclaringType != type) { propertyInfo = propertyInfo.DeclaringType.GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance); } propertyInfo.SetValue(target, newValue, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty, null, null, CultureInfo.InvariantCulture); } catch (TargetInvocationException exception) { throw ExceptionEnlightenment.PrepareForRethrow(exception.InnerException); } }
/// <summary> /// Constructs an object which has a private constructor. /// </summary> /// <param name="specification"> /// The specification object. /// </param> /// <param name="args"> /// The arguments to pass to the constructor. /// </param> /// <typeparam name="T"> /// The concrete object type. /// </typeparam> /// <returns> /// The constructed object. /// </returns> /// <exception cref="Exception"> /// Returns any exception thrown by <see cref="Activator.CreateInstance(System.Type,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo)"/>. Unwraps <see cref="TargetInvocationException"/>. /// </exception> public static T InstancePrivateObject <T>(this IContextSpecification specification, params object[] args) { try { return((T)Activator.CreateInstance(typeof(T), BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, args, null)); } catch (TargetInvocationException exception) { throw ExceptionEnlightenment.PrepareForRethrow(exception.InnerException); } }
/// <summary> /// The invoke private. /// </summary> /// <param name="target"> The target object which we want to invoke. </param> /// <param name="methodName"> The method Name. </param> /// <param name="args"> The args to pass to the method. </param> public static void InvokePrivate(object target, string methodName, object[] args = null) { try { target.GetType().InvokeMember(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, target, args); } catch (TargetInvocationException exception) { throw ExceptionEnlightenment.PrepareForRethrow(exception.InnerException); } }
/// <summary> /// This will be called by the <see cref="InstrumentTestsAspect"/> aspect. Rethrows any exception logged during the test run. /// </summary> /// <param name="testMethodInfo"> /// The <see cref="MethodBase"/> instance that describes the executing test. /// </param> /// <param name="isExceptionResilient"> /// <c>true</c> if the test is set to ignore some exception. <c>false</c> otherwise. /// </param> void IContextSpecification.OnTestMethodCalled(MethodBase testMethodInfo, bool isExceptionResilient) { var descriptionAttribute = testMethodInfo != null ? testMethodInfo.GetCustomAttributes(typeof(NUnit.Framework.DescriptionAttribute), false) .Cast <NUnit.Framework.DescriptionAttribute>() .SingleOrDefault() : null; var description = descriptionAttribute != null ? descriptionAttribute.Description : "N/A"; Trace.WriteLine(headerFooter); Trace.Write("** "); Trace.WriteLine(description.Replace("\n", "\n** ")); OutputContextTypeName(this.contextType); if (this.ThrownException == null) { return; } if (isExceptionResilient) { // we don't care about exceptions right now var testMethodsInContext = TypeInvestigationService.GetTestMethods(this.contextType, true) .Concat(TypeInvestigationService.GetAllContextSpecificationTypes(this.contextType) .SelectMany(nestedType => TypeInvestigationService.GetTestMethods(nestedType, true))); var expectedExceptions = testMethodsInContext.SelectMany(testMethod => testMethod.GetCustomAttributes(typeof(ExpectedExceptionAttribute), false)) .Cast <ExpectedExceptionAttribute>() .Select(attr => attr.ExpectedException) .Distinct() .ToArray(); if (expectedExceptions.Contains(null) || expectedExceptions.Any(exceptionTypeToIgnore => exceptionTypeToIgnore.IsInstanceOfType(this.ThrownException))) { // Exception is ignored return; } } throw ExceptionEnlightenment.PrepareForRethrow(this.ThrownException); }