Como unidad de prueba de un temporizador basado en System.Threading.Timer en .NET El System.Threading.Timer tiene un método de devolución de llamadaUnidad System.Threading.Timer de prueba en .NET
Respuesta
Puede probar la unidad no creando realmente una dependencia directa en System.Threading.Timer
. En su lugar, cree una interfaz ITimer
y un contenedor alrededor de System.Threading.Timer
que la implemente.
primer lugar usted necesita para convertir la devolución de llamada a un evento, por lo que se puede hacer parte de una interfaz:
public delegate void TimerEventHandler(object sender, TimerEventArgs e);
public class TimerEventArgs : EventArgs
{
public TimerEventArgs(object state)
{
this.State = state;
}
public object State { get; private set; }
}
A continuación, cree una interfaz:
public interface ITimer
{
void Change(TimeSpan dueTime, TimeSpan period);
event TimerEventHandler Tick;
}
Y un envoltorio:
public class ThreadingTimer : ITimer, IDisposable
{
private Timer timer;
public ThreadingTimer(object state, TimeSpan dueTime, TimeSpan period)
{
timer = new Timer(TimerCallback, state, dueTime, period);
}
public void Change(TimeSpan dueTime, TimeSpan period)
{
timer.Change(dueTime, period);
}
public void Dispose()
{
timer.Dispose();
}
private void TimerCallback(object state)
{
EventHandler tick = Tick;
if (tick != null)
tick(this, new TimerEventArgs(state));
}
public event TimerEventHandler Tick;
}
Obviamente se agregarían las sobrecargas del constructor y/o Change
método que necesita usar desde el Threading.Timer
. Ahora puede probar la unidad nada dependiendo de ITimer
con un temporizador falsa:
public class FakeTimer : ITimer
{
private object state;
public FakeTimer(object state)
{
this.state = state;
}
public void Change(TimeSpan dueTime, TimeSpan period)
{
// Do nothing
}
public void RaiseTickEvent()
{
EventHandler tick = Tick;
if (tick != null)
tick(this, new TimerEventArgs(state));
}
public event TimerEventHandler Tick;
}
Cada vez que desee simular una garrapata, simplemente llame a RaiseTickEvent
en las falsificaciones.
[TestMethod]
public void Component_should_respond_to_tick
{
ITimer timer = new FakeTimer(someState);
MyClass c = new MyClass(timer);
timer.RaiseTickEvent();
Assert.AreEqual(true, c.TickOccurred);
}
voy a probarlo en el de la misma manera que cualquier otra clase pero con intervalos de tiempo cortos para evitar que la prueba de la unidad se ejecute durante un tiempo prolongado. Otro enfoque es probar tu propio código solo y usar un temporizador simulado (por ejemplo, NMock), pero depende de cómo sea el diseño de tu código. ¿Puedes publicar algunos fragmentos de código?
Si el tiempo simplemente cambia el método de devolución de llamada, entonces solo necesita verificar la exactitud de ese método, no cómo funciona la hora del sistema.
Además de eso, recomiendo usar el MultimediaTimer en su lugar - es mucho más preciso.
Digamos que quiero un temporizador que se enciende una vez por hora. ¿Recomiendas el 'MultimediaTimer' para todos? :) –
Sí, y combínelo con .NET's Dispatcher si necesita devolver el hilo de la interfaz de usuario. –
Afortunadamente cualquiera que sea esta característica es una parte más grande de permite configurar el intervalo del temporizador. Debería poder usar esa interfaz para inyectar un breve intervalo adecuado para la prueba unitaria. Tengo la pregunta el valor de esta prueba: ¿Estás probando el intervalo (sin sentido) o que la rutina se llama aproximadamente cada cierto tiempo?
- 1. System.Threading.Timer
- 2. .NET Unidad de prueba de corredor para iOS
- 3. Unidad de prueba automatizada de Gen Herramientas para .NET
- 4. .net mvc2 prueba de unidad de extensión HtmlHelper personalizada
- 5. . Prueba de unidad .NET - Mejores prácticas para ocultar costuras de prueba en el código de versión
- 6. (Unidad) Prueba de ArrayAdapter
- 7. Prueba de unidad CacheManager
- 8. Unidad de prueba EJB
- 9. unidad que prueba una unidad de trabajo
- 10. Generador de caso de prueba de unidad
- 11. unidad prueba olor
- 12. Unidad Prueba Assert.AreEqual failed
- 13. Sockets de prueba de unidad
- 14. Prueba de Unidad de Curado
- 15. Ejemplos de prueba de unidad?
- 16. Herencia de prueba de unidad
- 17. ASP.NET - Unidad MembershipProvider prueba
- 18. Eliminar prueba :: unidad
- 19. instaladores de prueba de unidad
- 20. EJB unidad Caso de prueba
- 21. Prueba de unidad post mortem
- 22. Prueba de unidad código matemático
- 23. Prueba de unidad Descripción pregunta
- 24. Prueba de unidad Clases estáticas
- 25. de prueba Unidad clases particulares
- 26. Prueba de unidad de dependencia de código
- 27. Messagebox y prueba de unidad
- 28. Mocking HTTPResponse en una prueba de unidad
- 29. Usando httpcontext en la prueba de unidad
- 30. unidad de prueba decoradores en Python
Esto se ve bien, pero ¿por qué creas tu propio delegado en lugar de simplemente usar el delegado TimerCallback del BCL? – Shaun
@Shaun: Porque ese delegado no es un controlador de eventos válido. Los manejadores de eventos tienen una firma específica: 'object sender, TEventArgs e' donde' TEventArgs: EventArgs'. – Aaronaught
Eso sí, estos días con cierres que se soportan tan fácilmente, si quisiera algo rápido y sucio, no sé si me molestaría con toda la declaración del evento y el cableado, podría simplemente pasar una 'Acción 'en cambio. – Aaronaught