测试由异步方法

时间:2016-03-22 07:50:06

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

我尝试使用包含异步方法的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>());
}

但这并不奏效。因为在断言之前没有执行异步代码。

2 个答案:

答案 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();
}

通过MSDN Magazine

答案 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>());
}