throwsexception example ejemplos c# async-await c#-5.0 xunit.net

c# - example - ¿Cómo manejar las excepciones generadas por las tareas en el comando Assert.thhrows de xUnit.net?



assert c# ejemplos (2)

La siguiente prueba asíncrona de xUnit.net con un lambda marcado con el modificador async falla al informar que no se lanzó ninguna excepción:

[Theory, AutoWebData] public async Task SearchWithNullQueryThrows( SearchService sut, CancellationToken dummyToken) { // Fixture setup // Exercise system and verify outcome Assert.Throws<ArgumentNullException>(async () => await sut.SearchAsync(null, dummyToken)); // Teardown }

Para asegurarme de que se ArgumentNullException realmente una ArgumentNullException utilicé explícitamente un bloque try-catch . Funcionó, sin embargo, el código resultante no está limpio (en comparación con la primera prueba):

[Theory, AutoWebData] public async Task SearchWithNullQueryThrows( SearchService sut, CancellationToken dummyToken) { // Fixture setup var expected = typeof(ArgumentNullException); Type actual = null; // Exercise system try { await sut.SearchAsync(null, dummyToken); } catch (ArgumentNullException e) { actual = e.GetType(); } // Verify outcome Assert.Equal(expected, actual); // Teardown }

¿Por qué Assert.Throws<T> con la lambda marcada con el modificador async ?


Si también necesita devolver la excepción para verificarla, esto podría ser útil:

public static async Task<Exception> AssertThrowsAsync<TException>(Func<Task> func) { var expected = typeof (TException); Exception exception = null; Type actual = null; try { await func(); } catch (Exception e) { actual = e.GetType(); exception = e; } Assert.NotNull(exception); Assert.Equal(expected, actual); return exception; }


Actualizar

Esto se ha resuelto en xUnit 2, con la adición de Assert.ThrowsAsync .

Estoy sospechando que Assert.Throws no es async . Recomiendo plantear este problema con el equipo de xUnit, sugiriendo que se ThrowsAsync un ThrowsAsync .

Un delegado async en este caso está devolviendo Task o Task<T> , y la ArgumentNullException no se elimina directamente del delegado; en su lugar, se coloca en la Task ( Task.Exception.InnerException ). Assert.Throws espera que la excepción se Assert.Throws directamente del delegado, no se coloque en una propiedad del valor de retorno.

Puede crear su propio AssertEx.ThrowsAsync como tal:

public static async Task ThrowsAsync<TException>(Func<Task> func) { var expected = typeof(TException); Type actual = null; try { await func(); } catch (Exception e) { actual = e.GetType(); } Assert.Equal(expected, actual); }

Que se puede utilizar como tal:

[Theory, AutoWebData] public async Task SearchWithNullQueryThrows( SearchService sut, CancellationToken dummyToken) { // Fixture setup // Exercise system and verify outcome await AssertEx.ThrowsAsync<ArgumentNullException>(async () => await sut.SearchAsync(null, dummyToken)); // Teardown }

Yo uso un enfoque similar en MSTest.