- メソッド(プライベートまたはパブリック)をテストしていません-クラスの動作を検証しています。また、一部の動作を検証していない場合は、それが実装されたとは言えません。この動作を呼び出す方法はいくつかあります。クラスのパブリックインターフェイス、または依存関係にあるイベントです。また、動作の呼び出しによってパブリックインターフェイスが到達するものが変更される必要はなく、依存関係との相互作用も重要です。
- 以下の例を参照してください-このような「隠された」動作をテストする方法を示しています。
- 以下の例を参照してください-責任を分割し、依存性を注入し、それらをモックする方法を示しています。
実際、クラスにはあまりにも多くの責任があります。1つはタスクをスケジュールし、もう1つはアクションを実行します。クラスを1つの責任を持つ2つの別々のクラスに分割してみてください。
したがって、スケジューリングはスケジューラーに行きます:)スケジューラーのAPIは次のようになります:
public interface IScheduler
{
event EventHandler<SchedulerEventArgs> Alarm;
void Start();
void Stop();
}
今のところスケジューラーを忘れてください。2番目のクラスに戻って実装します。これにより、いくつかの警告が表示されます。最初にテストに行きましょう(Moqを使用):
[Test]
public void ShouldStopDisplayingWarningsWhenTimeIsOut()
{
Mock<IDisplay> display = new Mock<IDisplay>();
Mock<IScheduler> scheduler = new Mock<IScheduler>();
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());
}
実装の記述:
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]
public void ShouldNotStopDisplayingWarningsWhenTimeRemains()
{
Mock<IDisplay> display = new Mock<IDisplay>(MockBehavior.Strict);
Mock<IScheduler> scheduler = new Mock<IScheduler>(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));
}
テストに失敗しました。ああ、残り時間の条件が必要です:
private void Scheduler_Alarm(object sender, SchedulerEventArgs e)
{
if (e.RemainingTime > 0)
return;
_display.Execute(_name, WarningState.Ending, null);
_scheduler.Stop();
}
クラスのテストを引き続き作成できます。このテストは、スケジューラーアラートの処理と、表示されているいくつかの警告の実行を担当します。終了したら、IScheduler
インターフェイスの実装を記述できます。System.Windows.Forms.TimerまたはSystem.ThreadingTimer、あるいはその他の方法で、スケジューリングをどのように実装するかは重要ではありません。