寻找更好的单元测试实现

时间:2013-04-10 14:08:45

标签: unit-testing xunit xunit.net fluent-assertions

我使用xUnit和FluentAssertions编写单元测试,我遇到了以下问题。由于我尚未实现catch的{​​{1}}(GetCountriesAsync),我会在这个位置投放新的WebException

此代码是我使测试实际按预期工作的唯一方法。我添加了原生的xUnit实现,因为FluentAssertions只是语法糖。

NotImplementedException

虽然我发现这个实现更好,但它不起作用。

[Fact]
public async Task GetCountriesAsyncThrowsExceptionWithoutInternetConnection()
{
    // Arrange
    Helpers.Disconnect(); // simulates network disconnect
    var provider = new CountryProvider();

    try
    {
        // Act
        var countries = await provider.GetCountriesAsync();
    }
    catch (Exception e)
    {
        // Assert FluentAssertions
        e.Should().BeOfType<NotImplementedException>();

        // Assert XUnit
        Assert.IsType<NotImplementedException>(e);
    }
}

由于VS2012 / ReSharper已建议删除测试方法的冗余[Fact] public async Task GetCountriesAsyncThrowsExceptionWithoutInternetConnection3() { // Arrange Helpers.Disconnect(); // simulates network disconnect var provider = new CountryProvider(); // Act / Assert FluentAssertions provider.Invoking(async p => await p.GetCountriesAsync()) .ShouldThrow<NotImplementedException>(); // Act / Assert XUnit Assert.Throws<NotImplementedException>(async () => await provider.GetCountriesAsync()); } 关键字,我将async替换为async Task,测试仍然表现为相同的,所以我怀疑无法等待异步void,他们会被解雇并被遗忘。

有没有办法用xUnit / FluentAssertions正确实现?我想我必须使用我的第一个实现,因为我看不到像Action这样的任何功能。

2 个答案:

答案 0 :(得分:1)

实际上,FA 2.0特别支持处理异步异常。只需查看AsyncFunctionExceptionAssertionSpecs中的单元测试。各种例子。

答案 1 :(得分:0)

关于FluentAssertions,我已将以下内容添加到我的代码中:

using System;
using System.Threading.Tasks;

namespace FluentAssertions
{
    public static class FluentInvocationAssertionExtensions
    {
        public static Func<Task> Awaiting<T>(this T subject, Func<T, Task> action)
        {
            return () => action(subject);
        }
    }
}

现在你可以这样做:

_testee.Awaiting(async x => await x.Wait<Foo>(TimeSpan.Zero))
        .ShouldThrow<BarException>();

_teste.Wait<T>会返回Task<T>。 方法Awaiting的命名也是有意义的,因为对方法的纯调用不会导致调用者捕获异常,您需要使用等待来执行此操作。