Come unità di prova di un timer in base a System.Threading.Timer in .NET Lo System.Threading.Timer ha un metodo di callbacktest unità System.Threading.Timer in .NET
risposta
È possibile testare l'unità non creando effettivamente una dipendenza diretta su System.Threading.Timer
. Creare invece un'interfaccia ITimer
e un wrapper attorno a System.Threading.Timer
che lo implementa.
In primo luogo è necessario convertire la richiamata a un evento, in modo che possa essere parte di un'interfaccia:
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; }
}
Poi creare un'interfaccia:
public interface ITimer
{
void Change(TimeSpan dueTime, TimeSpan period);
event TimerEventHandler Tick;
}
E un wrapper:
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;
}
Ovviamente si aggiungerebbe qualsiasi sovraccarico del costruttore e/o Change
metodo che è necessario utilizzare da Threading.Timer
. Ora è possibile test di unità qualsiasi cosa a seconda ITimer
con un timer falso:
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;
}
Ogni volta che si desidera simulare un segno di spunta, basta chiamare RaiseTickEvent
sul falso.
[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);
}
mi metterà alla prova nel allo stesso modo di qualsiasi altra classe ma con intervalli di tempo brevi per evitare che il test unitario funzioni a lungo. Un altro approccio è quello di testare solo il proprio codice e l'utilizzo di un timer simulato (ad esempio NMock), ma dipende da come è il design del codice. Puoi pubblicare alcuni frammenti di codice?
Se l'ora cambia semplicemente il metodo di callback, è sufficiente verificare la correttezza di tale metodo e non il modo in cui funziona l'ora del sistema.
Oltre a questo, mi consiglia di utilizzare il MultimediaTimer invece - è molto più preciso.
Dire che voglio un timer che spara una volta all'ora. Raccomandi 'MultimediaTimer' per tutti? :) –
Sì, e combinalo con .NET Dispatcher se è necessario restituire il thread dell'interfaccia utente. –
Si spera che qualunque sia questa funzione è una parte più ampia di consente di configurare l'intervallo del timer. Dovresti essere in grado di usare quell'interfaccia per iniettare un breve intervallo adatto per il test dell'unità. Ho la domanda sul valore di questo test: stai testando l'intervallo (inutile) o che la routine viene effettivamente chiamata all'incirca ogni tanto?
- 1. Test unità XML: XmlUnit alternative per .NET?
- 2. Test unità Test delle applicazioni .NET basate su database
- 3. Test unità di base e test unità
- 4. .net mvc2 HtmlHelper personalizzato estensione test unità di estensione
- 5. scrittura unità di test in C++
- 6. Test dell'unità Mongodb in .NET
- 7. Test delle unità in PHP?
- 8. Confronto oggetti in test unità
- 9. Unità test decoratori in Python
- 10. Posso interrompere un System.Threading.Timer
- 11. System.Threading.Timer non si avvia?
- 12. Test unità MVC 4 RedirectToAction
- 13. (unità) Test di ArrayAdapter
- 14. Setup test unità Qt
- 15. Test unità C# [TestInitialize]
- 16. Timer più affidabile di System.Threading.Timer
- 17. Unità prese test
- 18. Test unità post mortem
- 19. "Test unità" un report
- 20. Test unità Descrizione domanda
- 21. API REST test unità
- 22. Test 4 unità Silverlight
- 23. System.Timers.Timer vs System.Threading.Timer
- 24. Unità Test Architettura Domanda
- 25. C# - Test unità, Mock?
- 26. Struttura directory test unità
- 27. Test unità CXF
- 28. Copertura test unità Python
- 29. Unità regole di test
- 30. unità immobiliare eccezione test
Questo sembra buono, ma perché si crea il proprio delegato invece di utilizzare semplicemente il delegato TimerCallback dal BCL? – Shaun
@Shaun: poiché quel delegato non è un gestore eventi valido. I gestori di eventi hanno una firma specifica: 'object mittente, TEventArgs e' dove' TEventArgs: EventArgs'. – Aaronaught
Ti dispiace, in questi giorni con le chiusure supportate così facilmente, se volevo qualcosa di veloce e sporco, non so se mi sarei preoccupato di tutte le dichiarazioni degli eventi e della connessione, potrei semplicemente passare in un 'Azione 'invece. – Aaronaught