Question

Je tente actuellement de mettre en œuvre une classe StopWatch. L'interface est quelque chose comme:

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

En gros mon application devra utiliser un StopWatch, mais à des fins de test, il serait bien d'avoir un moyen de modifing artifially un résultat de StopWatches, de sorte que c'est la raison pour laquelle je fais toute ma référence de code Un IStopWatch au lieu de la System.Stopwatch de .NET.

Comme je suis en train de développer ce test-première, je vais devoir faire un code pour ma classe StopWatch seulement après avoir écrit ses essais. Je l'ai déjà réalisé que les tests que je vais faire ne vont pas être tests unitaires, comme j'utilise la classe System.Stopwatch de .NET en interne.

Alors, dans mon undertanding, la seule chose que je peux faire sont maintenant des tests qui ressemblent à ce qui suit:

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

Je sais que je ne peux pas courir tout aussi souvent que mes tests unitaires, mais je pense qu'il n'y a rien que je puisse faire à ce sujet. Est-ce mon approche correcte ou suis-je manque quelque chose?

Merci

Modifier

Alors je me suis retrouvé à la suite les deux conseils pour Quinn351 et Sjoerd et quelque chose qui utilise un code DateTimes au lieu de la classe Chronomètre de .NET:

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

Cela me permet de faire d'autres implémentations qui ont getter / setters pour les deux dates pour que je puisse faire revenir GetTimeElapsed () tout ce que je veux.

Était-ce utile?

La solution

Votre classe chronomètre obtient probablement la date et l'heure de quelque part. Faire un objet qui retourne la date actuelle. Ce serait une classe très simple. Lors du test, passer dans un mock objet au lieu, qui retourne une date de faux et de temps. De cette façon, vous pouvez prétendre dans votre test comme si plusieurs secondes se sont écoulées.

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

Autres conseils

Pourquoi "modifing artifially un résultat de chronomètres" ?! Quel est le but de l'essai si vous allez modifier vos résultats?

En ce qui concerne le test, vous devez également tester la méthode d'arrêt et vous devriez vérifier si le nombre de secondes est environ 60 fois plus que la quantité de minutes.

La classe que vous écrivez peut également utiliser StopWatch en interne, puis modifier les résultats comme l'a demandé (vous pouvez toujours revenir aux résultats originaux).

PS:. Les noms méthode doit être plus courte et ne pas avoir soulignements

Un problème est que le chronomètre est précis sur les processeurs avec des vitesses d'horloge variables à savoir les plus de courant, comme on peut le voir avec la discussion suivante

C # Chronomètre montre le temps incorrect

Donc, en utilisant Thread.Sleep wont vous donner un temps précis. Vous feriez mieux de mettre en œuvre votre propre version de Chronomètre en utilisant DateTime.Now

En aparté au-dessus EDIT: Ne pas utiliser cette méthode pour déterminer le temps écoulé! Il ne fonctionne pas quand:

  • Liste élément
  • l'horloge ou le fuseau horaire est mis en
  • l'heure d'été commence ou se termine
  • l'horloge est par ailleurs peu fiable (par exemple à l'intérieur d'une machine virtuelle)

... et probablement un certain nombre d'autres conditions.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top