在 UnitTest Thread.sleep(1300) 中只等待 ~300ms

In UnitTest Thread.sleep(1300) is only waiting ~300ms

我正在尝试测试在设定的时间(在我的例子中是 1300 毫秒)后调用 SendMessage 会在事件处理程序中给出正确的结果。但是 Thread.Sleep(1300) 并没有等待 1300 毫秒,它只等待了大约 300 毫秒。

单元测试

using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using mvce;

namespace mvceTest
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            Class1 c = new Class1();

            string finalResult = "";

            c.AnEvent += (o, entry) => { finalResult = entry; };

            DateTime start = DateTime.Now;

            while (finalResult == "")
            {
                Thread.Sleep(1300);
                c.SendMessage("message");
            }

            DateTime end = DateTime.Now;

            Assert.AreEqual(1300, (end - start).Milliseconds);

            Assert.AreEqual("message", finalResult);
        }
    }
}

Class1

using System;

namespace mvce
{
    public class Class1
    {
        private readonly object _lock = new object();

        private event EventHandler<string> _anEvent;

        public event EventHandler<string> AnEvent
        {
            add
            {
                lock (_lock)
                {
                    _anEvent += value;
                }
            }
            remove
            {
                lock (_lock)
                {
                    _anEvent -= value;
                }
            }
        }

        public void SendMessage(string message)
        {
            _anEvent?.Invoke(this, message);
        }

    }
}

我得到的输出是

Assert.AreEqual failed. Expected:<1300>. Actual:<302>.

显然我不希望它们相等,这只是为了举例。

我也试过System.Threading.Tasks.Task.Delay(1300).Wait();,结果一样

如何让测试线程等待正确的时间?为什么 Thread.Sleep 不起作用?

在您的断言中,您使用的是:

Assert.AreEqual(1300, (end - start).Milliseconds);

请尝试使用以下内容:

Assert.AreEqual(1300, (end - start).TotalMilliseconds);

TimeSpan.TotalMilliseconds :

Gets the value of the current TimeSpan structure expressed in whole and fractional milliseconds.

TimeSpan.Milliseconds :

Gets the milliseconds component of the time interval represented by the current TimeSpan structure.

它返回 300 毫秒的原因是因为您的 TimeSpan 的毫秒部分实际上是 300 毫秒,而且您的 TimeSpan 的秒部分也是 1 秒。

您应该使用 TotalMilliseconds 而不是 Milliseconds。 另外,最好用秒表来计时。

此代码显示线程确实休眠了 1300 毫秒:

 static void Main(string[] args)
    {
        Class1 c = new Class1();

        string finalResult = "";

        c.AnEvent += (o, entry) => { finalResult = entry; };

        Stopwatch sw = new Stopwatch();
        DateTime start = DateTime.Now;

        while (finalResult == "")
        {
            sw.Start();
            Thread.Sleep(1300);
            var ms = sw.ElapsedMilliseconds;
            Console.WriteLine(ms);
            c.SendMessage("message");
        }
        DateTime end = DateTime.Now;
        Console.WriteLine((end - start).TotalMilliseconds);
}