web-dev-qa-db-fra.com

xUnit n'attend pas le test asynchrone

Sur VS 2013, je ne peux pas faire échouer ce test asynchrone.

J'ai xUnit 1.8.0.1539 (installé à partir de nuget), avec l'extension xUnit Test Runner VS (0.99.5). Tout courant, AFAIK.

Il se trouve que j'ai également des références Moq, AutoFixture et FluentAssertions dans le test unitaire, mais je ne pense pas que cela soit important (mais je l'admets au cas où ce serait le cas).

J'ai effectué des tests unitaires asynchrones dans d'autres domaines de ma solution et ils fonctionnent.

Je manque quelque chose avec ces tests nouvellement créés, et je ne peux pas dire ce que je manque ou ce que je fais mal.

NOTE Le code SUT n'est pas censé être complet. J'essaie simplement d'obtenir le feu rouge en premier, avant d'écrire le code pour faire passer le test au vert.

Voici le code de test:

using System.Threading.Tasks;
using FluentAssertions;
using Xunit;

namespace MobileApp.Proxy.Test
{
public class WhenRetrievingPriceDataFromClient
{
    [Fact]
    public async Task GroupReportIsReturnedWithSomeData()
    {
        // arrange
        var sut = new Client();

        // act
        var actual = await sut.GetReportGroupAsync();

        // assert

        // Xunit test
        Assert.Null(actual);
        Assert.NotNull(actual);
        // FluentAssertions
        actual.Should().BeNull();
        actual.Should().NotBeNull();
    }
}
}

Et voici le code SUT:

using System;
using System.Diagnostics;
using System.Net.Http;
using System.Threading.Tasks;
using MobileApp.Proxy.Properties;

namespace MobileApp.Proxy
{
    public class Client
    {
        public async Task<ReportGroup> GetReportGroupAsync()
        {
            return await Task.FromResult(new ReportGroup());
        }
    }
}

Évidemment, ce test devrait échouer! Les Asserts pour Null et NotNull ne peuvent pas réussir tous les deux, donc ma conclusion est que le test se termine avant d'avoir fini de recevoir la réponse du SUT.

Qu'est-ce que j'ai raté?

OU, y a-t-il une meilleure façon que j'aurais dû commencer un test asynchrone pour m'assurer qu'il échoue avant d'écrire le code SUT?

20

Vous avez besoin de xUnit 1.9 pour que les tests unitaires async fonctionnent correctement.

24
Stephen Cleary

Les tests asynchrones sont pris en charge dans xUnit v1.9 ou version ultérieure. Si vous êtes bloqué avec une version antérieure, vous devrez faire quelque chose comme ceci:

[Fact]
public void GroupReportIsReturnedWithSomeData()
{
     GroupReportIsReturnedWithSomeDataAsync().Wait();
}

private async Task GroupReportIsReturnedWithSomeDataAsync()
{
    // arrange
    var sut = new Client();

    // act
    var actual = await sut.GetReportGroupAsync();

    // assert

    // Xunit test
    Assert.Null(actual);
    Assert.NotNull(actual);
    // FluentAssertions
    actual.Should().BeNull();
    actual.Should().NotBeNull();
}

Fondamentalement, la méthode de test se bloque jusqu'à ce que la méthode de test asynchrone se termine, que ce soit en raison d'une réussite ou d'une erreur (par exemple, une assertion ayant échoué). En cas d'erreur, les exceptions se propageront au thread de test principal via Wait().

Vous voudrez peut-être passer un délai d'attente à Wait() afin que votre test échoue s'il ne s'est pas terminé après un certain temps. Tel qu'écrit, le test pourrait se bloquer indéfiniment si la méthode async ne se termine jamais.

5
Mike Strobel