【问题标题】:How to unit test method that uses await delay如何对使用等待延迟的方法进行单元测试
【发布时间】:2017-09-22 08:37:33
【问题描述】:

我创建了虚拟代码来描述我的问题,如下所示:

  public class ItemGenerator
    {
        public bool isStopped;
        public List<int> list = new List<int>();
        public void GetItems(int itemsPerSecond)
        {
            int i = 0;
            while (!isStopped)
            {
                list.add(i);
                await Task.Delay(1000);
                i++;
            }
        }
    }



    [Test]
    public void TestGetItmes()
    {
        ItemGenerator gen = new ItemGenerator();

        gen.GetItems(1000);

        await  Task.Delay(5000).ContinueWith(t =>
        {
            gen.isStopped = true;
            Assert.True(gen.list.Count() == (5 * 1000));
        });
    }

现在的问题是断言会偶尔失败,我想这与 CPU 性能有关,而且不能保证 1000 的延迟总是 1000 毫秒,但是这种 UT 的最佳方法是什么?逻辑?

【问题讨论】:

  • 你的 GetItems 方法应该被等待(所以它应该返回一个任务)。你的测试也应该如此 (public Task TestGetItmes())
  • 您的示例可能失败,但您不能在GetItems 中使用await,因为它不是async
  • @Iqon 是的,我看到了,想知道这是否是要走的路......
  • @IronHide 静态框架方法在单元测试中总是存在问题。如果项目足够大,我总是将这些方法包装在帮助服务中。 (IoC 和 DependencyInjection 将使这更容易)。否则,这些方法中的大多数根本无法测试。我的意思是,你可以等待 10 秒,但单元测试应该很快。如果可以mock该方法,就可以将时间减少到零。

标签: c# unit-testing


【解决方案1】:

以下是我的处理方法——首先使用内置的CancellationToken

public class ItemGenerator
{
    public List<int> List { get; } = new List<int>();

    public async Task GetItems(CancellationToken token)
    {
        int i = 0;
        while(!token.IsCancellationRequested)
        {
            List.Add(i);
            await Task.Delay(1000);
            i++;
        }
    }
}

那么你的测试可以使用CancellationTokenSource,特别是CancelAfter方法:

var gen = new ItemGenerator();

CancellationTokenSource src = new CancellationTokenSource();
src.CancelAfter(5000);
await gen.GetItems(src.Token);

请注意,如果更合适的话,您可以将 CancellationToken 传递给 ItemGenerator 的构造函数,而不是方法。

【讨论】:

  • 好的,但仍然不能保证项目的数量会匹配预期值,因为测试中的延迟与方法中的延迟可能不相等?我的主要问题是结果不同,我认为这是由于延迟本身波动。
  • 说真的,应该有一个规则,强制用户对反对票提供反馈。否则有什么意义?
猜你喜欢
  • 2018-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多