我尝试使用包含异步方法的NUnit测试类。我不知道如何以正确的方式做到这一点。
我的课程看起来像这样:
public class EditorViewModel:INotifyPropertyChanged
{
public void SetIdentifier(string identifier)
{
CalcContentAsync();
}
private async void CalcContentAsync()
{
await SetContentAsync();
DoSomething();
}
private async Task SetContentAsync()
{
Content = await Task.Run<object>(() => CalculateContent());
RaisePropertyChanged("Content");
}
public object Content { get; private set; }
...
}
如何在NUnit中编写一个测试,检查Content-Property是否设置为正确的值?我想做那样的事情:
[Test]
public void Content_WhenModifierIsXXX_ReturnsSomeViewModel()
{
var viewModel = new EditorViewModel();
viewModel.SetIdentifier("XXX");
Assert.That(viewModel.Content, Is.InstanceOf<ISomeContentViewModel>());
}
但这并不奏效。因为在断言之前没有执行异步代码。
答案 0 :(得分:1)
您的SetIdentifier
方法也是async
(或者您需要将其设为async
,因为您在其中等待操作。然后您的方法可能看起来像下一个:
public async Task SetIdentifier(string identifier)
{
await SetContentAsync();
DoSomething();
}
现在你可以在单元测试中等待它:
[Test]
public async Task Content_WhenModifierIsXXX_ReturnsSomeViewModel()
{
var viewModel = new EditorViewModel();
await viewModel.SetIdentifier("XXX");
Assert.That(viewModel.Content, Is.InstanceOf<ISomeContentViewModel>());
}
您还可以使用变通方法以同步方式调用测试:
[Test]
public async Task Content_WhenModifierIsXXX_ReturnsSomeViewModel()
{
Task.Run(async () =>
{
var viewModel = new EditorViewModel();
await viewModel.SetIdentifier("XXX");
Assert.That(viewModel.Content, Is.InstanceOf<ISomeContentViewModel>());
}).GetAwaiter().GetResult();
}
答案 1 :(得分:0)
使用async
时,您应始终返回任务。否则就会“发射并忘记”,你绝对无法与Task
进行互动。
因此,您应该更改SetIdentifier的签名以返回Task
,如下所示:
public async Task SetIdentifier(string identifier)
{
await SetContentAsync();
DoSomething();
}
然后您可以等待测试中的操作完成:
[Test]
public async void Content_WhenModifierIsXXX_ReturnsSomeViewModel()
{
var viewModel = new EditorViewModel();
await viewModel.SetIdentifier("XXX");
Assert.That(viewModel.Content, Is.InstanceOf<ISomeContentViewModel>());
}
或者,如果您的测试运行员不支持async
:
[Test]
public void Content_WhenModifierIsXXX_ReturnsSomeViewModel()
{
var viewModel = new EditorViewModel();
viewModel.SetIdentifier("XXX").Wait();
Assert.That(viewModel.Content, Is.InstanceOf<ISomeContentViewModel>());
}