multithreading - thread - multitarea en python
¿Cuál es la mejor manera de probar la unidad de un método asincrónico? (3)
¿Hay alguna otra manera mejor que simplemente dormir un poco y luego buscar un indicador establecido por la devolución de llamada?
Reemplace la bandera con un identificador de espera. En lugar de establecer el indicador, configure el identificador de espera. En lugar de dormir y verificar si la bandera está activada, espere el indicador de espera ... y aguarde con un tiempo de espera, de modo que si se despierta debido a la expiración del temporizador en lugar de despertarse porque se disparó el identificador en el que estaba esperando por la devolución de llamada, entonces usted sabe que la prueba falló (es decir, la devolución de llamada no se invocó dentro del período de tiempo de espera).
Parece que no puedo encontrar una respuesta de .NET a este problema, que habría pensado que sería bastante común.
¿Cuál es el mejor patrón para probar unidades un método asincrónico?
Obviamente necesito llamar al método y luego ver si la devolución de llamada se dispara, pero ¿hay una mejor manera que simplemente dormir un poco y luego buscar un indicador que se establece mediante la devolución de llamada? La gestión de las banderas se vuelve un poco desordenada cuando hay varias pruebas ejecutándose.
Divida el código de modo que la lógica esté en un bit de código síncrono invocado por un contenedor asíncrono fino.
Entonces, la mayoría de sus pruebas unitarias pueden probar el código síncrono.
Normalmente utilizo un delegado anónimo y un indicador de espera. Por ejemplo, tengo una función en mi presentador llamada SetRemoteTableName. Cuando se establece el nombre, también genera un evento. Quiero probar ese evento, que se genera de forma asíncrona. La prueba se ve así:
[TestMethod]
[WorkItem(244)]
[Description("Ensures calling SetRemoteTableName with a valid name works
AND raises the RemoteTableNameChange event")]
public void SetRemoteTableNamePositive()
{
string expected = "TestRemoteTableName";
string actual = string.Empty;
AutoResetEvent are = new AutoResetEvent(false);
SQLCECollectorPresenter presenter = new SQLCECollectorPresenter();
presenter.RemoteTableNameChange += new EventHandler<GenericEventArg<string>>(
delegate(object o, GenericEventArg<string> a)
{
actual = a.Value;
are.Set();
});
presenter.SetRemoteTableName(expected);
Assert.IsTrue(are.WaitOne(1000, false), "Event never fired");
Assert.AreEqual(actual, expected);
}