【问题标题】:Unit Test Finishes before Thread.Sleep time单元测试在 Thread.Sleep 时间之前完成
【发布时间】:2016-04-29 00:52:26
【问题描述】:

我的程序是一个简单的计时器(它是番茄钟)。我正在尝试将单元测试整合到我的个人项目中。

我在每个计时器类的 run() 方法上运行我的测试,并断言 endTime - startTime 在我设置计时器的时间的 1 秒内。

MyTimer.run() 调用 Thread.sleep(timerMilliseconds)。

我的单元测试通过的时间少于每个计时器设置的时间。

这怎么可能?

例如。休息时间设置为 5 秒,单元测试通过

[TestMethod]
        public void testRun () {
            TimeSpan fiveSeconds = new TimeSpan(5000);
            Rest rest = new Rest(fiveSeconds, null);
            TimeSpan startTime = DateTime.Now.TimeOfDay;
            try {
                rest.run();
            }
            catch (Exception e) {
                Assert.Fail(e.ToString());
            }

            Assert.AreEqual(startTime.Add(fiveSeconds).TotalMilliseconds, DateTime.Now.TimeOfDay.TotalMilliseconds, 1000 , "Actual sleep time not expected");
        }


 public class Rest : Session {

        private TimeSpan timeSpan;

        public override void run () {
            Thread.Sleep(base.getTimer().Milliseconds); **//SOLVED: SHOULD READ base.getTimer().TotalMilliseconds**
        }

        public Rest (TimeSpan timeSpan, Cycle cycle) : base(timeSpan, cycle) {
            this.timeSpan = timeSpan;
        }
    }


 public abstract class Session {
        private readonly TimeSpan timer;
        protected Cycle cycle;

        public TimeSpan getTimer () {
            return this.Timer;
        }

        protected Session (TimeSpan minutes, Cycle cycle) {
            this.timer = minutes;
            this.cycle = cycle;
        }

        public abstract void run ();
    }

【问题讨论】:

  • 'now' 是该变量的糟糕名称。当您使用它时,它不再是“现在”。 startTime 不会那么混乱。
  • base.getMinutes() 返回的是什么? 5 秒将产生 0 分钟,其中的 Milliseconds 也将是 0,所以我认为这是无需等待即可运行。
  • @Cory 这是一个命名不佳的变量。 base.getMinutes() 返回一个在创建时初始化的 TimeSpan,而不是 TimeSpan.Minutes 属性。在发布帮助之前,我应该重构我的变量名。对不起
  • 什么是“休息”?我以为它是 .Net 类型,但显然不是。由于是代码行为不端,因此种类很重要的是要弄清楚它实际上是什么。
  • @DougClark:没问题,只是好奇。另一件事是你可能会在你的断言中允许一些容差,比如 10-20 毫秒。我不知道它是否会精确匹配到毫秒,但它可能会接近。

标签: c# .net visual-studio unit-testing


【解决方案1】:

基本问题是这样的:

public override void run () {
    Thread.Sleep(base.getTimer().Milliseconds);
}

您想为TotalMilliseconds 睡觉,而不是MillisecondsTimeSpanMilliseconds 组件在这种情况下为 0)。

也就是说,更广泛地说,您只是不想对调用 Thread.Sleep 的方法进行单元测试,尤其是不想测试调用的持续时间。该测试将需要很长时间,并且是脆弱的和近似的;在单元测试中绝对要避免的 3 个属性。为了使这段代码可测试,您需要在某个接口后面抽象对Thread.Sleep 的调用,然后您可以在单元测试中模拟这些接口(请参阅依赖注入)。然后,您的单元测试可以验证传递给 Sleep() 的值是否符合您的预期,并且您会发现这个错误,而不会出现测试对 Thread.Sleep 的真实调用会导致的所有问题。

【讨论】:

  • 哈!像往常一样,就在我的鼻子底下。而且我绝对计划实施我在 stackoverflow 上找到的其他解决方案,这些解决方案测试调用线程睡眠的方法。这只是为了确保我的基本流程正确。谢谢!
猜你喜欢
  • 2019-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-02
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
相关资源
最近更新 更多