I\'ve got a class that has a private member that has for type System.Windows.Forms.Timer
. There\'s also a private method that is being called every time my time
Actually your class have too many responsibilities - one is scheduling some task, and another - executing some actions. Try to split your class into two separate classes with single responsibilities.
So, scheduling goes to scheduler :) API of scheduler could be like:
public interface IScheduler
{
event EventHandler Alarm;
void Start();
void Stop();
}
Forget about scheduler for now. Return and implement your second class, which will display some warnings. Let's go test first (with Moq):
[Test]
public void ShouldStopDisplayingWarningsWhenTimeIsOut()
{
Mock display = new Mock();
Mock scheduler = new Mock();
Foo foo = new Foo("Bar", scheduler.Object, display.Object);
scheduler.Raise(s => s.Alarm += null, new SchedulerEventArgs(0));
display.Verify(d => d.Execute("Bar", WarningState.Ending, null));
scheduler.Verify(s => s.Stop());
}
Write implementation:
public class Foo
{
private readonly IScheduler _scheduler;
private readonly IDisplay _display;
private readonly string _name;
public Foo(string name, IScheduler scheduler, IDisplay display)
{
_name = name;
_display = display;
_scheduler = scheduler;
_scheduler.Alarm += Scheduler_Alarm;
_scheduler.Start();
}
private void Scheduler_Alarm(object sender, SchedulerEventArgs e)
{
_display.Execute(_name, WarningState.Ending, null);
_scheduler.Stop();
}
}
Test passes. Write another one:
[Test]
public void ShouldNotStopDisplayingWarningsWhenTimeRemains()
{
Mock display = new Mock(MockBehavior.Strict);
Mock scheduler = new Mock(MockBehavior.Strict);
scheduler.Setup(s => s.Start());
Foo foo = new Foo("Bar", scheduler.Object, display.Object);
scheduler.Raise(s => s.Alarm += null, new SchedulerEventArgs(1));
}
Test failed. Ah, you need condition for remaining time:
private void Scheduler_Alarm(object sender, SchedulerEventArgs e)
{
if (e.RemainingTime > 0)
return;
_display.Execute(_name, WarningState.Ending, null);
_scheduler.Stop();
}
You can continue writing tests for your class, which responsible for handling scheduler alerts and executing some warnings on display. When you finish, you can write implementation for your IScheduler
interface. It does not matter how you will implement scheduling - via System.Windows.Forms.Timer or via System.ThreadingTimer, or some other way.