Comment simuler des événements qui provoquent des exceptions pour tester les blocs try / catch?

14

Je comprends comment fonctionnent les exceptions et comment les intercepter et les gérer en C #, mais comment puis-je simuler des événements susceptibles de provoquer une exception pour m'assurer qu'elle est correctement interceptée? Par exemple, est-il possible d'exécuter une application dans une sorte de banc d'essai où il est possible de simuler des problèmes de réseau, des problèmes de base de données, etc.? Les exceptions de par leur nature semblent difficiles à reproduire, ce qui rend difficile de garantir que votre code peut y faire face.

Bien que je développe principalement en utilisant C # /. NET / Visual Studio, des réponses ou des ressources relatives à d'autres langages pourraient être utiles.

Piers Myers
la source
Une autre solution possible est décrite dans cet article MSDN: Fault Injection Testing avec TestApi
Giorgi

Réponses:

13

1) Si vous suiviez le modèle d'injection de dépendances, vous pourriez remplacer les implémentations réelles de certaines parties par les simulations qui lèveraient des exceptions lorsque vous en auriez besoin. Cela nécessiterait cependant de vous que vous conceviez initialement votre application d'une manière spécifique ou que vous la réorganisiez complètement.

Comme:

public class SqlUsersRepository : IUsersRepository
{
    public void RegisterNewUser (User newUser)
    {
        throw new SqlException ("Connection timeout");
    }
}

Ici, cependant, nous aurions le problème que le code de la consommation ne devrait pas se préoccuper de gérer les exceptions d'implémentation concrètes.

2) Une autre approche consiste à remplacer certains appels de méthode par vos wrappers personnalisés.

Au lieu de:

FileStream fs = File.OpenRead (path);

tu utilises:

FileStream fs = File.OpenRead_Test (path);

en fournissant une méthode d'extension personnalisée (juste une idée rapide):

public static FileStream OpenRead_Test (this System.IO.File file, string path)
{
    throw new FileNotFoundException ();
}

la source
3

Vous devez examiner les cadres de simulation.

Avec ceux-ci, vous utilisez l'injection de dépendance pour appeler la fausse base de données (disons) plutôt que la vraie. Cela signifie que vous avez un contrôle total sur ce qui est retourné pour chaque appel.

Vous configurez ensuite un test qui, lorsqu'il est appelé, lève simplement l'exception souhaitée:

public void Test1()
{
    throw new NullArgumentException();
}

Votre test réussit lorsque votre code gère cela correctement.

ChrisF
la source
3

La moquerie et l'injection ne peuvent vous amener jusqu'à présent et nécessitent de grands changements d'approche dans certains cas.

Si vous ne voulez pas repenser votre application pour l'adapter à un cadre de test, alors ce dont vous avez vraiment besoin, c'est d'un hôte ou d'un environnement truqué d'erreurs. Il existe de nombreuses façons de simuler la lenteur du réseau pendant notre panne (même les outils de test Microsoft en ont un peu dans la zone de test Web). J'ai eu le plus de succès en mettant des machines derrière un routeur qui peut être altéré pour changer des simulations en coordination avec un ensemble de bases de données pour produire des erreurs et des scripts pour changer les erreurs que la base de données produit.

Même avec cela, si vous allez assez vite ou assez loin vers le matériel, il y a des erreurs telles que des problèmes de concurrence et des échecs d'écriture retardés que vous ne pouvez pratiquement pas simuler. Parfois, vous devez les provoquer pour de vrai et d'autres fois, vous n'avez qu'à travailler sans filet de sécurité.

Facture
la source
D'accord - dans certains cas, vous ne pouvez pas vous permettre les frais généraux liés à l'injection de dépendances dans votre code de version, par exemple. Ce n'est pas un problème quotidien, mais cela peut arriver.
Steve314