【问题标题】:Why do async unit tests fail when the async/await keywords aren't used?为什么不使用 async/await 关键字时异步单元测试会失败?
【发布时间】:2015-03-19 03:39:15
【问题描述】:

根据this discussion,下面两种方法应该没有区别:

public async Task Foo()
{
    await DoSomethingAsync();
}

public Task Foo()
{
    return DoSomethingAsync();
}

实际上,对于非常简单的方法, 不带 async/await 关键字的调用似乎是首选,因为它们消除了一些开销。

但是,这显然在单元测试中并不总是有效。

MSTest

[TestClass]
public class AsyncTest
{
    [TestMethod]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [TestMethod]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}

NUnit

[TestFixture]
public class AsyncTest
{
    [Test]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [Test]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}

XUnit

public class AsyncTest
{
    [Fact]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [Fact]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}
  • 在所有情况下,Test1 通过。
  • 在 MSTest 中,Test2 出现在测试运行程序中,但它没有运行。
  • 在 NUnit 中,Test2 被忽略,消息为:

    测试方法具有非空返回类型,但没有预期结果

  • 在 XUnit 中,Test2 通过。

由于在所有情况下任务仍然是等待的,async 关键字影响 NUnit 和 MSTest 测试运行器的原因是什么?也许是一些反射问题?

【问题讨论】:

标签: c# unit-testing nunit async-await mstest


【解决方案1】:

听起来那些测试运行器可能正在使用反射来检查返回Task 的方法是否真的异步方法。这并不意味着该方法的行为会有所不同如果它们被运行 - 但它们只是没有被运行。

就像这样说:

public string Name { get; set; }

相当于:

private string name;
public Name { get { return name; } set { name = value; } }

就行为而言,它们在逻辑上是相同的,但如果你足够努力地反思,你就能分辨出不同之处。在这种特殊情况下,还有其他更细微的差异,但适用相同的一般原则。

看起来在当前的 NUnit 代码中(在撰写本文时)检测位于 AsyncInvocationRegion.cs

诚然,编写返回Task 但不使用异步方法的单元测试至少不寻常 - 但远非不可能。

【讨论】:

  • 我明白了。所以 NUnit 特别期望编译器用AsyncStateMachineAttribute 修饰该方法。我想这可以解释它。 MSTest 可能正在做类似的事情。
  • @MattJohnson:我怀疑你当然可以自己添加这个属性——只是为了愚弄它。可能值得一试,看看 MSTest 做了什么......
  • 是的。添加了[AsyncStateMachine(typeof(Task))],现在通过 MSTest 和 NUnit。虽然我认为我会坚持使用 async/await 关键字。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-26
  • 1970-01-01
  • 2019-04-05
  • 2013-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多