最初にストップウォッチクラステストを開発する方法は?
-
30-09-2019 - |
質問
現在、実装しようとしています StopWatch
クラス。インターフェイスは次のようなものです。
interface IStopWatch {
void Run();
void Stop();
int SecondsElapsed { get; }
int MinutesElapsed { get; }
}
基本的に私のアプリはaを使用する必要があります StopWatch
, 、しかし、テスト目的のために、人工的に修正する方法があるといいのですが StopWatch
es 's' sotが私がすべてのコードを参照している理由です IStopWatch
.netの代わりに System.Stopwatch
.
このテストファーストを開発しようとしているので、私は自分のコードを作成する必要があります StopWatch
テストを作成した後にのみクラス。 .netを使用しているので、私がやろうとしているテストはユニットテストにならないことにすでに気付きました System.Stopwatch
内部的にクラス。
ですから、私の授業では、私が今できる唯一のことは、次のように見えるテストです。
[TestMethod]
public void Right_After_Calling_Run_Elapsed_Minutes_Equals_Zero() {
IStopWatch stopWatch = new StopWatch();
stopWatch.Run();
Assert.AreEqual<int>(0, stopWatch.ElapsedMinutes);
}
[TestMethod]
public void One_Second_After_Run_Elapsed_Seconds_Equals_One() {
IStopWatch stopWatch = new StopWatch();
stopWatch.Run();
Thread.Sleep(1000 + 10);
Assert.AreEqual<int>(1, stopWatch.ElapsedSeconds);
}
[TestMethod]
public void Sixty_Seconds_After_Run_Elapsed_Minutes_Equals_One() {
IStopWatch stopWatch = new StopWatch();
stopWatch.Run();
Thread.Sleep(60 * 1000 + 1000);
Assert.AreEqual<int>(1, stopWatch.ElapsedMinutes);
}
ユニットテストほど頻繁にこれを実行できないことは知っていますが、これについてできることは何もないと思います。私のアプローチは正しいですか、それとも何かが足りませんか?
ありがとう
編集
そこで、私はQuinn351とSjoerdのアドバイスの両方に従い、.NETのStopWatchクラスの代わりにDateTimesを使用するものをコーディングしました。
public class MyStopWatch : IMyStopWatch {
private DateTime? firstDateTime = null;
private DateTime? secondDateTime = null;
private bool isRunning = false;
public void Start() {
isRunning = true;
firstDateTime = DateTime.Now;
}
public void Stop() {
isRunning = false;
secondDateTime = DateTime.Now;
}
public void Reset() {
firstDateTime = null;
secondDateTime = null;
isRunning = false;
}
public TimeSpan GetTimeElapsed() {
return secondDateTime.Value.Subtract(firstDateTime.Value);
}
}
これにより、両方の日付のgetter/setterを持つ他の実装を作成できるため、gettimeelapsed()を返すことができます。
解決
あなたのストップウォッチクラスは、おそらくどこかから日付と時刻を取得します。現在の日付を返すオブジェクトを作成します。これは非常にシンプルなクラスになります。テストするときは、aを渡します モック 代わりに、偽の日付と時刻を返すオブジェクト。これにより、テストでは何秒も経過しているかのようにふりをすることができます。
class DateTime {
public Date getDate() {
return System.DateTime.Now();
}
}
class MockDateTime {
public Date getDate() {
return this.fakeDate;
}
}
class StopwatchTest {
public void GoneInSixtySeconds() {
MockDateTime d = new MockDateTime();
d.fakeDate = '2010-01-01 12:00:00';
Stopwatch s = new Stopwatch();
s.Run();
d.fakeDate = '2010-01-01 12:01:00';
s.Stop();
assertEquals(60, s.ElapsedSeconds);
}
}
他のヒント
なぜ「ストップウォッチ」の「結果」を「アーティカルに変更する」のでしょうか?!結果を変更する場合、テストする目的は何ですか?
テストについては、STOPメソッドをテストする必要があります。また、秒数が数分の約60倍高いかどうかをテストする必要があります。
書いているクラスは、StopWatchを内部で使用してから、要求に応じて結果を変更することもできます(いつでも元の結果に戻ることができます)。
PS:メソッド名は短く、下線がないはずです。
1つの問題は、次の説明でわかるように、クロック速度が変動するプロセッサでは正確ではないことです。
したがって、スレッドを使用すると、正確な時間が得られません。 DateTime.nowを使用して、独自のバージョンのStopwatchを実装することをお勧めします
上記の編集の余地として:この方法を使用して経過時間を決定しないでください!次の場合はうまく機能しません
- リストアイテムをリストします
- 時計またはタイムゾーンが設定されています
- 夏時間の節約は始まります
- それ以外の場合は時計が信頼できません(たとえば、VM内)
...そしておそらく他の多くの条件。