/// <summary> /// Executes a parameterless synchronous or async delegate and returns the exception it throws, if any. /// </summary> internal static Exception RecordException(Delegate parameterlessDelegate, string parameterName) { Guard.ArgumentNotNull(parameterlessDelegate, parameterName); Guard.ArgumentValid( parameterlessDelegate.GetMethodInfo().GetParameters().Length == 0, $"The actual value must be a parameterless delegate but was {parameterlessDelegate.GetType().Name}.", nameof(parameterName)); Guard.ArgumentNotAsyncVoid(parameterlessDelegate, parameterName); using (new TestExecutionContext.IsolatedContext()) { if (AsyncToSyncAdapter.IsAsyncOperation(parameterlessDelegate)) { try { AsyncToSyncAdapter.Await(parameterlessDelegate.DynamicInvokeWithTransparentExceptions); } catch (Exception ex) { return(ex); } } else { try { parameterlessDelegate.DynamicInvokeWithTransparentExceptions(); } catch (Exception ex) { return(ex); } } } return(null); }
/// <summary> /// Check that setup and teardown methods marked by certain attributes /// meet NUnit's requirements and mark the tests not runnable otherwise. /// </summary> protected void CheckSetUpTearDownMethods(MethodInfo[] methods) { foreach (MethodInfo method in methods) { if (method.IsAbstract) { MakeInvalid("An abstract SetUp and TearDown methods cannot be run: " + method.Name); } else if (!(method.IsPublic || method.IsFamily)) { MakeInvalid("SetUp and TearDown methods must be public or protected: " + method.Name); } else if (method.GetParameters().Length != 0) { MakeInvalid("SetUp and TearDown methods must not have parameters: " + method.Name); } else if (AsyncToSyncAdapter.IsAsyncOperation(method)) { if (method.ReturnType == typeof(void)) { MakeInvalid("SetUp and TearDown methods must not be async void: " + method.Name); } else if (!Reflect.IsVoidOrUnit(AwaitAdapter.GetResultType(method.ReturnType))) { MakeInvalid("SetUp and TearDown methods must return void or an awaitable type with a void result: " + method.Name); } } else { if (!Reflect.IsVoidOrUnit(method.ReturnType)) { MakeInvalid("SetUp and TearDown methods must return void or an awaitable type with a void result: " + method.Name); } } } }