Frage

Ich versuche derzeit eine StopWatch Klasse zu implementieren. Die Schnittstelle ist so etwas wie:

interface IStopWatch {
    void Run();
    void Stop();
    int SecondsElapsed { get; }
    int MinutesElapsed { get; }
}

Im Grunde meine App benötigen einen StopWatch verwenden, aber für Testzwecke wäre es schön, einen Weg zu haben, von artifially einem StopWatches' Ergebnisse modifing, so dass der Grund, warum ich jeden Bezug meines Code mache einen IStopWatch statt .NET ist System.Stopwatch.

Als ich versuche, diesen Test-First zu entwickeln, werde ich Code für meine StopWatch Klasse machen muß erst nach seinen Tests zu schreiben. Ich habe bereits erkannt, dass die Tests, die ich tun werde nicht Komponententests sein würden, wie ich intern von .NET System.Stopwatch Klasse.

Also, meinen undertanding, das einzige, was ich jetzt tun kann, Tests sind, dass wie folgt aussehen:

[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);            
}

Ich weiß, ich kann nicht einfach diese läuft so oft wie meine Einheit-Tests, aber ich denke, es gibt nichts, was ich dagegen tun kann. Ist mein Ansatz richtig oder ich etwas fehlt?

Danke

Bearbeiten

So landete ich beide Quinn351 und Sjoerd die Ratschläge Verfolgung und codiert etwas, dass Verwendungen Datetime statt .NET die Stoppuhr-Klasse:

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);
    }
}

Dies ermöglicht es mir, andere Implementierungen zu machen, die Getter / Setter für beide Termine haben, damit ich GetTimeElapsed machen kann () zurück, was ich will.

War es hilfreich?

Lösung

Ihre Stoppuhr Klasse wird wahrscheinlich das Datum und die Zeit von irgendwo. Machen Sie ein Objekt, das das aktuelle Datum zurückgibt. Dies wäre eine sehr einfache Klasse sein. Bei der Prüfung, übergibt in einem Mock Objekt statt, die ein gefälschtes Datum und Uhrzeit zurückzugibt. Auf diese Weise können Sie in Ihrem Test so tun, als ob viele Sekunden vergangen sind.

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);
    }
}

Andere Tipps

Warum sollte "artifially modifing ein Stoppuhr Ergebnisse" ?! Was ist der Sinn und Zweck zu testen, ob Ihre Ergebnisse gehen ändern?

Wie zum Testen Sie auch die Stop-Methode testen sollten und Sie sollen prüfen, ob die Anzahl der Sekunden in etwa 60-mal mehr als die Menge von Minuten ist.

Die Klasse Sie schreiben auch intern Stoppuhr verwenden könnte und dann Ergebnisse ändern wie gewünscht (dann können Sie immer auf die ursprünglichen Ergebnisse zurück).

PS:. Methodennamen sollte kürzer sein und nicht die Unterstreichungen haben

Ein Problem ist, dass Stoppuhr auf Prozessoren mit variablen Taktraten nicht genau das heißt die meisten aktuellen, wie bei der folgenden Diskussion gesehen werden kann

C # Stoppuhr zeigt falsche Zeit

So verwenden Thread.Sleep pflegen Sie eine genaue Zeit. Sie wäre besser, Ihre eigene Version der Stoppuhr zu implementieren DateTime.Now mit

Als Seite, um die EDIT oben: Verwenden Sie diese Methode nicht verstrichene Zeit zu bestimmen! Es funktioniert nicht gut, wenn:

  • Liste item
  • die Uhr oder Zeitzone wird Satz
  • Sommer beginnt oder endet
  • der Takt auf andere Weise unzuverlässig ist (z.B. in einer VM)

... und wahrscheinlich eine Reihe anderer Bedingungen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top