Autofixture: Créez une autre GuardClauseAssertion qui prend en charge les méthodes marquées "async".

Créé le 1 mars 2019  ·  12Commentaires  ·  Source: AutoFixture/AutoFixture

Comme discuté dans #268, la classe GuardClauseAssertion n'attend pas la fin des tâches, ce qui la rend incapable de valider les méthodes rapides sans

C'est tout à fait compréhensible, puisque le fail fast est en effet la meilleure option. Néanmoins, il semble impossible d'implémenter un comportement d' async .

enhancement

Commentaire le plus utile

@ploeh Fondamentalement, la méthode _any_ async n'est pas rapide. Considérez l'exemple suivant :

```c#
Tâche publique asynchroneGardéOuvertGénériqueMéthodeRetourTâcheRésultat(objet argument)
{
if (arg == null) throw new ArgumentNullException(nameof(arg));

await Task.Yield();

return default;

}
```

Cette méthode ne lance pas si vous l'appelez null . Au lieu de cela, le Task échoué est renvoyé. Par conséquent, la GuardClauseAssertion dans sa forme actuelle échoue et se plaint d'une clause de garde manquante.

Dans une application réelle, presque tout le code est async , donc chaque invocation est awaited et l'exception est levée immédiatement. Il est donc tout à fait normal que le principe "fast-fail" soit violé sous une forme que vous devriez await Task pour voir l'exception.

Bien sûr, vous pouvez réécrire le code d'une manière ou d'une autre pour le faire échouer immédiatement (créer une fonction privée avec le mot-clé async et y déplacer toute la logique), mais cela n'a aucun sens pratique.

Tous les 12 commentaires

il semble impossible d'implémenter le comportement _fail fast_ lorsqu'il s'agit de méthodes marquées avec le mot-clé async .

Comment? Pouvez vous donner un exemple?

@ploeh Fondamentalement, la méthode _any_ async n'est pas rapide. Considérez l'exemple suivant :

```c#
Tâche publique asynchroneGardéOuvertGénériqueMéthodeRetourTâcheRésultat(objet argument)
{
if (arg == null) throw new ArgumentNullException(nameof(arg));

await Task.Yield();

return default;

}
```

Cette méthode ne lance pas si vous l'appelez null . Au lieu de cela, le Task échoué est renvoyé. Par conséquent, la GuardClauseAssertion dans sa forme actuelle échoue et se plaint d'une clause de garde manquante.

Dans une application réelle, presque tout le code est async , donc chaque invocation est awaited et l'exception est levée immédiatement. Il est donc tout à fait normal que le principe "fast-fail" soit violé sous une forme que vous devriez await Task pour voir l'exception.

Bien sûr, vous pouvez réécrire le code d'une manière ou d'une autre pour le faire échouer immédiatement (créer une fonction privée avec le mot-clé async et y déplacer toute la logique), mais cela n'a aucun sens pratique.

Dans une application réelle, presque tout le code est async , donc chaque invocation est awaited et l'exception est levée immédiatement.

C'est un bon point; J'accepte cet argument.

Je suis parfois distrait lorsque quelqu'un affirme ou laisse entendre (avec peu de preuves) que quelque chose est _impossible_...

Je suis parfois distrait quand quelqu'un affirme ou laisse entendre (avec peu de preuves) que quelque chose est impossible...

Ouais, c'est assez juste

Maintenant, laissez-moi essayer de réfléchir à la façon dont je peux reconcevoir GuardClauseAssertion pour ne pas avoir de drapeau booléen - je ne l'aime pas non plus, pour être juste. A plus tard dans PR.

Maintenant, laissez-moi essayer de réfléchir à la façon dont je peux reconcevoir GuardClauseAssertion pour ne pas avoir de drapeau booléen

Je pense que, comme @moodmosaic l'a suggéré, une nouvelle classe pourrait être un meilleur design. Je n'ai pas étudié la question de près, donc je me réserve le droit de me tromper

Voici la solution que j'ai utilisé.

  1. Supprimer le mot-clé async de la signature de la méthode
  2. Créez une méthode imbriquée avec le mot-clé async
  3. Mettez les clauses de garde dans la partie externe de la méthode
  4. Appelez la méthode imbriquée et retournez les résultats

Exemple:

public Task<int> GetNumberAsync(MyObject obj)
{
    // Fail-fast behavior
    if (request is null)
        throw new ArgumentNullException(nameof(obj));

    async Task<int> work()
    {
        var items = await obj.GetItemsAsync(); // whatever you need to call
        return items.Count();
    }

    return work();
}

Cela a été une bonne solution pour moi. Merci de votre aide.

@mniak Intéressant d'avoir un exemple concret de ce que @zvirja a suggéré ici .

Personnellement je n'aime pas trop ça car on pollue la méthode avec des "trucs" au profit du framework de test, ce qui me sent vraiment mauvais et je ne voudrais pas que mon équipe utilise ce modèle.

Gardez-le ouvert pour implémenter le support de manière native. Un jour. Dans un futur proche. Ou juste un jour.

Salut. Nous avons trébuché exactement sur ce problème et avons été surpris qu'il n'existe pas de bonne solution jusqu'à présent.
Y a-t-il des raisons de ne pas implémenter une nouvelle classe pour cela ?
Je ne connais pas les détails internes d'AutoFixture, mais si nous avions un MethodInfo disponible dans la classe GuardClauseAssertion pour la méthode à tester, nous pouvons jeter un œil à ses CustomAttributes et identifier s'il s'agit d'une méthode Async ou non (https :/ /stackoverflow.com/a/20350646). Donc, peut-être qu'un changement (bool contre nouvelle classe) n'est même pas nécessaire.

@zvirja @aivascu pourrait-on reconsidérer cela ? Je ne vois vraiment pas pourquoi en 2021, les méthodes asynchrones ne peuvent pas être testées correctement.

@Kralizek si j'ai bien lu la situation, la demande n'a pas été rejetée, et il y a même un PR qui la corrige.
J'ai jeté un bref coup d'œil au PR et je dois dire que je suis d'accord avec les commentaires qu'il a reçus.
Il ne reste donc plus qu'à mettre en œuvre les commentaires ou à déposer un nouveau PR avec les commentaires mis en œuvre.

Je ne pouvais pas voir le PR lié dans l'application mobile 😅

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

zvirja picture zvirja  ·  32Commentaires

Kralizek picture Kralizek  ·  40Commentaires

tommck picture tommck  ·  77Commentaires

thiagomajesk picture thiagomajesk  ·  11Commentaires

malylemire1 picture malylemire1  ·  12Commentaires