Quiero probar que establecer una determinada propiedad (o, más en general, ejecutar algún código) plantea un determinado evento en mi objeto. En ese sentido, mi problema es similar al Unit testing that an event is raised in C#, pero necesito muchas de estas pruebas y odio las repeticiones. Así que estoy buscando una solución más general, utilizando la reflexión.Prueba de unidad de que un evento se produce en C#, utilizando la reflexión
Idealmente, me gustaría hacer algo como esto:
[TestMethod]
public void TestWidth() {
MyClass myObject = new MyClass();
AssertRaisesEvent(() => { myObject.Width = 42; }, myObject, "WidthChanged");
}
Para la aplicación de la AssertRaisesEvent
, he llegado hasta aquí:
private void AssertRaisesEvent(Action action, object obj, string eventName)
{
EventInfo eventInfo = obj.GetType().GetEvent(eventName);
int raisedCount = 0;
Action incrementer =() => { ++raisedCount; };
Delegate handler = /* what goes here? */;
eventInfo.AddEventHandler(obj, handler);
action.Invoke();
eventInfo.RemoveEventHandler(obj, handler);
Assert.AreEqual(1, raisedCount);
}
Como se puede ver, mi problema se basa en crear un Delegate
del tipo apropiado para este evento. El delegado no debe hacer nada excepto invocar incrementer
.
Debido a todo el jarabe sintáctico en C#, mi noción de cómo los delegados y los eventos realmente funcionan es un poco brumosa. Esta es también la primera vez que incursiono en la reflexión. ¿Cuál es la parte faltante?
¡Deslizante! Si eso no responde la pregunta, nada lo hace. – Thomas
Hola Thomas, ejemplos de código actualizados después de volver a leer la pregunta original. Ajusté la API de EventMonitor para que sea un poco más concisa. Aclamaciones. :) –
Muy bien, de hecho, pero ni siquiera se acerca a manejar "eventos arbitrarios" como has afirmado en tu blog.Sin embargo, probablemente el 99% de todos los eventos en la naturaleza sigan las recomendaciones de MS, por lo que la falta de generalidad debería ser un gran problema en la práctica. –