Added Assert.ThrowsAny methods. Closes #25
This commit is contained in:
Родитель
7971a1b866
Коммит
710c2d1bc5
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit.Sdk;
|
||||
|
||||
|
@ -90,6 +91,46 @@ namespace Xunit
|
|||
return (T)Throws(typeof(T), await Record.ExceptionAsync(testCode));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the exact exception or a derived exception type is thrown.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the exception expected to be thrown</typeparam>
|
||||
/// <param name="testCode">A delegate to the code to be tested</param>
|
||||
/// <returns>The exception that was thrown, when successful</returns>
|
||||
/// <exception cref="ThrowsException">Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown</exception>
|
||||
public static T ThrowsAny<T>(Action testCode)
|
||||
where T : Exception
|
||||
{
|
||||
return (T)ThrowsAny(typeof(T), Record.Exception(testCode));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the exact exception or a derived exception type is thrown.
|
||||
/// Generally used to test property accessors.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the exception expected to be thrown</typeparam>
|
||||
/// <param name="testCode">A delegate to the code to be tested</param>
|
||||
/// <returns>The exception that was thrown, when successful</returns>
|
||||
/// <exception cref="ThrowsException">Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown</exception>
|
||||
public static T ThrowsAny<T>(Func<object> testCode)
|
||||
where T : Exception
|
||||
{
|
||||
return (T)ThrowsAny(typeof(T), Record.Exception(testCode));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the exact exception is thrown (and not a derived exception type).
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the exception expected to be thrown</typeparam>
|
||||
/// <param name="testCode">A delegate to the task to be tested</param>
|
||||
/// <returns>The exception that was thrown, when successful</returns>
|
||||
/// <exception cref="ThrowsException">Thrown when an exception was not thrown, or when an exception of the incorrect type is thrown</exception>
|
||||
public static async Task<T> ThrowsAnyAsync<T>(Func<Task> testCode)
|
||||
where T : Exception
|
||||
{
|
||||
return (T)ThrowsAny(typeof(T), await Record.ExceptionAsync(testCode));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the exact exception is thrown (and not a derived exception type).
|
||||
/// </summary>
|
||||
|
@ -140,6 +181,19 @@ namespace Xunit
|
|||
return exception;
|
||||
}
|
||||
|
||||
private static Exception ThrowsAny(Type exceptionType, Exception exception)
|
||||
{
|
||||
Assert.GuardArgumentNotNull("exceptionType", exceptionType);
|
||||
|
||||
if (exception == null)
|
||||
throw new ThrowsException(exceptionType);
|
||||
|
||||
if (!exceptionType.GetTypeInfo().IsAssignableFrom(exception.GetType().GetTypeInfo()))
|
||||
throw new ThrowsException(exceptionType, exception);
|
||||
|
||||
return exception;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the exact exception is thrown (and not a derived exception type), where the exception
|
||||
/// derives from <see cref="ArgumentException"/> and has the given parameter name.
|
||||
|
|
|
@ -289,6 +289,168 @@ public class ExceptionAssertsTests
|
|||
}
|
||||
}
|
||||
|
||||
public class ThrowsAny_Generic_Action
|
||||
{
|
||||
[Fact]
|
||||
public void ExpectExceptionButCodeDoesNotThrow()
|
||||
{
|
||||
try
|
||||
{
|
||||
Assert.ThrowsAny<ArgumentException>(() => { });
|
||||
}
|
||||
catch (AssertActualExpectedException exception)
|
||||
{
|
||||
Assert.Equal("(No exception was thrown)", exception.Actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StackTraceForThrowsIsOriginalThrowNotAssertThrows()
|
||||
{
|
||||
try
|
||||
{
|
||||
Assert.ThrowsAny<InvalidCastException>(() => ThrowingMethod());
|
||||
}
|
||||
catch (AssertActualExpectedException exception)
|
||||
{
|
||||
Assert.Contains("ThrowsAny_Generic_Action.ThrowingMethod", exception.StackTrace);
|
||||
Assert.DoesNotContain("Xunit.Assert", exception.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
static void ThrowingMethod()
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GotExpectedException()
|
||||
{
|
||||
Action testCode = () => { throw new ArgumentException(); };
|
||||
|
||||
var ex = Assert.ThrowsAny<ArgumentException>(testCode);
|
||||
|
||||
Assert.NotNull(ex);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GotDerivedException()
|
||||
{
|
||||
Action testCode = () => { throw new ArgumentException(); };
|
||||
|
||||
var ex = Assert.ThrowsAny<Exception>(testCode);
|
||||
|
||||
Assert.NotNull(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public class ThrowsAny_Generic_Func
|
||||
{
|
||||
[Fact]
|
||||
public void GuardClause()
|
||||
{
|
||||
Func<object> testCode = () => Task.Run(() => 0);
|
||||
|
||||
var ex = Record.Exception(() => Assert.ThrowsAny<Exception>(testCode));
|
||||
|
||||
Assert.IsType<InvalidOperationException>(ex);
|
||||
Assert.Equal("You must call Assert.ThrowsAsync, Assert.DoesNotThrowAsync, or Record.ExceptionAsync when testing async code.", ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExpectExceptionButCodeDoesNotThrow()
|
||||
{
|
||||
var accessor = new StubAccessor();
|
||||
|
||||
try
|
||||
{
|
||||
Assert.ThrowsAny<ArgumentException>(() => accessor.SuccessfulProperty);
|
||||
}
|
||||
catch (AssertActualExpectedException exception)
|
||||
{
|
||||
Assert.Equal("(No exception was thrown)", exception.Actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StackTraceForThrowsIsOriginalThrowNotAssertThrows()
|
||||
{
|
||||
var accessor = new StubAccessor();
|
||||
|
||||
try
|
||||
{
|
||||
Assert.ThrowsAny<InvalidCastException>(() => accessor.FailingProperty);
|
||||
}
|
||||
catch (AssertActualExpectedException exception)
|
||||
{
|
||||
Assert.Contains("StubAccessor.get_FailingProperty", exception.StackTrace);
|
||||
Assert.DoesNotContain("Xunit.Assert", exception.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GotExpectedException()
|
||||
{
|
||||
var accessor = new StubAccessor();
|
||||
|
||||
var ex = Assert.ThrowsAny<InvalidOperationException>(() => accessor.FailingProperty);
|
||||
|
||||
Assert.NotNull(ex);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GotDerivedException()
|
||||
{
|
||||
var accessor = new StubAccessor();
|
||||
|
||||
var ex = Assert.ThrowsAny<Exception>(() => accessor.FailingProperty);
|
||||
|
||||
Assert.NotNull(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public class ThrowsAnyAsync_Generic
|
||||
{
|
||||
[Fact]
|
||||
public async void ExpectExceptionButCodeDoesNotThrow()
|
||||
{
|
||||
try
|
||||
{
|
||||
await Assert.ThrowsAnyAsync<ArgumentException>(() => Task.Factory.StartNew(() => { }));
|
||||
}
|
||||
catch (AssertActualExpectedException exception)
|
||||
{
|
||||
Assert.Equal("(No exception was thrown)", exception.Actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void GotExpectedException()
|
||||
{
|
||||
Func<Task> testCode = () => Task.Factory.StartNew(() => { throw new ArgumentException(); });
|
||||
|
||||
var ex = await Assert.ThrowsAnyAsync<ArgumentException>(testCode);
|
||||
|
||||
Assert.NotNull(ex);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void GotDerivedException()
|
||||
{
|
||||
try
|
||||
{
|
||||
Func<Task> testCode = () => Task.Factory.StartNew(() => { throw new InvalidOperationException(); });
|
||||
|
||||
await Assert.ThrowsAnyAsync<Exception>(testCode);
|
||||
}
|
||||
catch (XunitException exception)
|
||||
{
|
||||
Assert.Equal("Assert.Throws() Failure", exception.UserMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Throws_NonGeneric_Action
|
||||
{
|
||||
[Fact]
|
||||
|
|
Загрузка…
Ссылка в новой задаче