我目前正在尝试实施 StopWatch 班级。界面就像:

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

基本上我的应用需要使用 StopWatch, ,但出于测试目的 StopWatchES的结果,所以这就是我将所有代码参考的原因 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的秒表类:

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()返回我想要的任何内容。

有帮助吗?

解决方案

您的秒表课可能会从某个地方获得日期和时间。制作一个返回当前日期的对象。这将是一个非常简单的课程。测试时,通过 嘲笑 而是返回假期和时间的对象。这样,您可以假装测试,就好像经过了很多秒一样。

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

其他提示

为什么“人工修改秒表的结果”?如果您要修改结果,则测试的全部目的是什么?

对于测试,您还应测试停止方法,您应该测试秒的数量是否比分钟数高约60倍。

您正在编写的类也可以内部使用秒表,然后根据要求修改结果(然后您始终可以返回原始结果)。

PS:方法名称应较短,并且不具有强调。

一个问题是,秒表在具有可变时钟速度的处理器上不准确,即大多数当前的速度,如以下讨论可以看出

C#秒表显示不正确的时间

因此,使用螺纹。睡眠不会给您准确的时间。您最好使用DateTime实现自己的秒表。

作为上述编辑的旁边:不要使用此方法来确定经过的时间!当:

  • 项目清单
  • 设置了时钟或时区
  • 日光节省开始或结束
  • 否则时钟是不可靠的(例如在VM内部)

...可能还有许多其他条件。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top