Added Assert.ThrowsAny methods. Closes #25

This commit is contained in:
Erik Schierboom 2014-03-23 14:19:49 +01:00 коммит произвёл Brad Wilson
Родитель 7971a1b866
Коммит 710c2d1bc5
2 изменённых файлов: 216 добавлений и 0 удалений

Просмотреть файл

@ -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]