【问题标题】:Async code inside of a test works but shows not run测试中的异步代码有效但显示未运行
【发布时间】:2020-08-29 06:45:27
【问题描述】:

我有一个测试有问题。它需要执行异步代码,但需要正确成功/失败。根据我的研究,构建异步测试实际上不会正确失败,所以我尝试了这样的方法:

[TestMethod]
public void VerifyAsynchronousSend()
{
    Task.Run(() => this.asbMessagingClient.SendAsync(new MessageInfo
    {
        Message = $"{MessageBody} async",
        AppId = AppId,
        Filter = Filter
    })).Wait();
}

消息确实写入了 ASB,并且确实成功了,但它在测试资源管理器中显示为 not run。有人可以帮我正确地构建这个吗?

这是它的执行代码:

public async Task SendAsync(MessageInfo messageInfo)
{
    var asbMessage = ConstructMessage(messageInfo);

    this.logger.WriteInfo($"ASB: Sending message async. {messageInfo} Message ID: {asbMessage.MessageId};");

    await this.TopicClient.SendAsync(asbMessage);
}

【问题讨论】:

  • Based on my research, building an async test won't actually fail properly - 什么研究?

标签: c# .net unit-testing asynchronous async-await


【解决方案1】:

如果你返回一个Task 对象,在你的单元测试中使用await 并将你的测试方法标记为async 是非常好的。事实上,问题中分享的文章确实很少有使用async/await编写的单元测试。文章说的是避免async void,在这种情况下,抛出的任何异常都将被忽略,并可能导致不正确的测试结果。

[TestMethod]
public async Task VerifyAsynchronousSend()
{
    await this.asbMessagingClient.SendAsync(new MessageInfo
    {
        Message = $"{MessageBody} async",
        AppId = AppId,
        Filter = Filter
    });

    //Assert
}

另一个good article 谈到在单元测试中避免异步无效。

【讨论】:

  • 该代码实际上产生了相同的结果,在它“工作”的地方,但测试显示没有运行。
  • 您能否详细说明“它在哪里工作”的含义。你的单元测试是否至少有一个断言?
【解决方案2】:

异步代码应该异步运行:

[TestMethod]
public async Task VerifyAsynchronousSend()
{
    await this.asbMessagingClient.SendAsync(new MessageInfo
    {
        Message = $"{MessageBody} async",
        AppId = AppId,
        Filter = Filter
    };

    Assert.Inconclusiev();
}

Async Programming : Unit Testing Asynchronous Code

【讨论】:

  • 该代码实际上产生了相同的结果,在它“工作”的地方,但测试显示没有运行。
  • 它没有显示。它只是没有显示结果,因为您没有提供结果。我更改了测试以发布一个不确定的结果。
【解决方案3】:
    [TestMethod]
    public void VerifyAsynchronousSend()
    {
        var result = this.asbMessagingClient.SendAsync(new MessageInfo
        {
            Message = $"{MessageBody} async",
            AppId = AppId,
            Filter = Filter
        })).Result;

        Assert.IsNotNull(result);
    }

【讨论】:

  • .Result 将给出一个包装的异常,如果有的话。 .GetAwaiter().GetResult() 应该在做你建议的事情时使用。在这种情况下,我不明白为什么 OP 不能使用普通的 await。
  • 它会发出警告,因为 await 仅与 async 方法一起使用。异步测试用例也没有任何意义。
  • 好吧,当你在测试异步的东西时,异步单元测试方法将是不可避免的。
  • @RoarS。 not 构建async 测试有很多指导。这是 Microsoft 的完整文章,docs.microsoft.com/en-us/archive/msdn-magazine/2014/november/…,我可以找到更多。
  • @MikePerrenoud 这并不是说你不应该有异步测试,它只是说它们不应该是 async void 测试方法,这当然是正确的,你不应该那样做。它在那篇文章中展示了如何正确测试异步方法。请注意,它所说的正确解决方案不是像您正在做的那样同步阻止任务。
猜你喜欢
  • 1970-01-01
  • 2018-06-05
  • 2019-11-12
  • 2015-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
相关资源
最近更新 更多