tiene sirven sintaxis significado reservadas que programacion para palabras instrucciones cuantas comandos c# unit-testing nunit async-await mstest

c# - sirven - ¿Por qué fallan las pruebas de unidad asíncrona cuando no se utilizan las palabras clave async/await?



palabras reservadas en programacion y su significado (1)

De acuerdo con esta discusión , no debería haber diferencia entre los dos métodos siguientes:

public async Task Foo() { await DoSomethingAsync(); } public Task Foo() { return DoSomethingAsync(); }

En realidad, parece que para métodos muy simples, la invocación sin las palabras clave async / await sería preferible, ya que eliminan algunos gastos generales.

Sin embargo, esto aparentemente no siempre funciona en pruebas unitarias.

MSTest

[TestClass] public class AsyncTest { [TestMethod] public async Task Test1() { await Task.Delay(0); } [TestMethod] public Task Test2() { return Task.Delay(0); } }

NUnit

[TestFixture] public class AsyncTest { [Test] public async Task Test1() { await Task.Delay(0); } [Test] public Task Test2() { return Task.Delay(0); } }

XUnit

public class AsyncTest { [Fact] public async Task Test1() { await Task.Delay(0); } [Fact] public Task Test2() { return Task.Delay(0); } }

  • En todos los casos, pasa Test1 .
  • En MSTest, Test2 aparece en el corredor de prueba, pero no se ejecuta.
  • En NUnit, se ignora Test2 , con el mensaje:

    El método de prueba tiene un tipo de devolución no nulo, pero no se espera ningún resultado

  • En XUnit, pasa Test2 .

Dado que las tareas aún son esperables en todos los casos, ¿qué tiene la palabra clave async que afecta a los corredores de prueba NUnit y MSTest? Tal vez algún problema de reflexión?


Parece que los corredores de prueba pueden estar usando la reflexión para comprobar si el método que devuelve Task realmente es un método asíncrono. Eso no significa que el método se comportaría de manera diferente si se ejecutaran , pero simplemente no se están ejecutando.

Es como decir que:

public string Name { get; set; }

es equivalente a:

private string name; public Name { get { return name; } set { name = value; } }

Son lógicamente los mismos en términos de comportamiento, pero si te esfuerzas lo suficiente con la reflexión, puedes notar la diferencia. En este caso particular, existen otras diferencias más sutiles, pero se aplica el mismo principio general.

Parece que en el código NUnit actual (en el momento de escribir esto) la detección está en AsyncInvocationRegion.cs .

Es cierto que al menos es inusual escribir una prueba unitaria para devolver una Task pero sin usar un método asíncrono, pero no es imposible.