mar*_*mnl 9 c# nunit async-await c#-5.0 .net-4.5
在一个引用等待的行上await的async方法Task<T>永远不会被命中之后,我很惊讶我的断点:
[Test]
public async void GetSomethingTest()
{
var service = SimpleIoc.Default.GetInstance<IService>();
var result = await service.TryGetSomethingAsync(20);
Assert.IsTrue(result.IsSuccess);
Assert.IsNotNull(result.ReturnValue);
}
Run Code Online (Sandbox Code Playgroud)
在第一Assert行放置一个断点永远不会被击中,但测试通过了.
当await返回时如何打破?
更新:我想这是因为测试框架不是await测试方法的调用,我使用的是NUnit 2.6.3并声称async支持,但是这是否需要在await我试图做之后打破,我不确定...
Tim*_*lds 14
问题是你的方法是async void.这有着"忘不了"的语义.
从概念上讲,您的方法正在使用async- await用法如下所示:
[Test]
public void GetSomethingTest()
{
var service = SimpleIoc.Default.GetInstance<IService>();
service.TryGetSomethingAsync(20).ContinueWith(t =>
{
var result = t.Result;
Assert.IsTrue(result.IsSuccess);
Assert.IsNotNull(result.ReturnValue);
});
}
Run Code Online (Sandbox Code Playgroud)
现在应该清楚问题是什么.您的测试方法,立即就返回TryGetSomethingAsync返回它Task.所以测试立即结束.由于没有抛出异常,因此取得了成功.
如果您的测试框架支持 - Task返回测试,您可以通过简单地将其返回类型更改为Task而不是来修复测试以执行您想要的操作void.
[Test]
public async Task GetSomethingTest()
{
var service = SimpleIoc.Default.GetInstance<IService>();
var result = await service.TryGetSomethingAsync(20);
Assert.IsTrue(result.IsSuccess);
Assert.IsNotNull(result.ReturnValue);
}
Run Code Online (Sandbox Code Playgroud)
这将在概念上转化为以下内容.
[Test]
public Task GetSomethingTest()
{
var service = SimpleIoc.Default.GetInstance<IService>();
return service.TryGetSomethingAsync(20).ContinueWith(t =>
{
var result = t.Result;
Assert.IsTrue(result.IsSuccess);
Assert.IsNotNull(result.ReturnValue);
});
}
Run Code Online (Sandbox Code Playgroud)
注意如何Task返回continuation,以便测试框架现在可以等待它,确保所有测试代码都有时间在测试完成之前运行.
(从技术上讲,一个框架也可以在这个async void案例中起作用,但我不知道为什么这将是一个很好的功能,所以我希望大多数人都不会处理它.)
如果您的测试框架不支持任务返回测试,则可以使用.Result而不是使用来修复测试await.
[Test]
public void GetSomethingTest()
{
var service = SimpleIoc.Default.GetInstance<IService>();
var result = service.TryGetSomethingAsync(20).Result;
Assert.IsTrue(result.IsSuccess);
Assert.IsNotNull(result.ReturnValue);
}
Run Code Online (Sandbox Code Playgroud)
这将简单地阻止当前线程,直到Task返回TryGetSomethingAsync完成.