97 votes

Comment puis-je vérifier que "aucune exception ne s'est produite" dans mon test unitaire MSTest ?

J'écris un test unitaire pour cette méthode qui renvoie "void". J'aimerais avoir un cas où le test passe quand aucune exception n'est levée. Comment puis-je écrire cela en C# ?

Assert.IsTrue(????)

(Je pense que c'est comme ça que je dois vérifier, mais qu'est-ce qui entre dans " ???").

J'espère que ma question est suffisamment claire.

0 votes

Utilisez-vous MSTest ou NUnit ?

3 votes

Dans MSTest, les exceptions non capturées provoquent automatiquement l'échec des tests. Essayez-vous de tenir compte des exceptions attrapées ?

0 votes

Vous pouvez consulter la rubrique "try-catch for C#", qui vous indiquera comment gérer les exceptions lancées ou non lancées.

149voto

Rob Levine Points 20793

Votre test unitaire échouera de toute façon si une exception est levée - vous n'avez pas besoin de mettre une assertion spéciale.

C'est l'un des rares scénarios où vous verrez des tests unitaires sans aucune assertion - le test échouera implicitement si une exception est levée.

Cependant, si vous voulez vraiment écrire une assertion pour cela - peut-être pour pouvoir attraper l'exception et rapporter "ne s'attendait pas à une exception mais a obtenu ceci...", vous pouvez faire ceci :

[Test]
public void TestNoExceptionIsThrownByMethodUnderTest()
{
    var myObject = new MyObject();

    try
    {
        myObject.MethodUnderTest();
    }
    catch (Exception ex)
    {
        Assert.Fail("Expected no exception, but got: " + ex.Message);
    }
}

(ce qui précède est un exemple pour NUnit, mais la même chose est vraie pour MSTest)

29voto

Clarkeye Points 49

Dans NUnit, vous pouvez utiliser :

Assert.DoesNotThrow(<expression>); 

pour vérifier que votre code ne lève pas d'exception. Bien que le test échouerait si une exception était levée même si aucun Assert ne l'entourait, l'intérêt de cette approche est que vous pouvez alors distinguer les attentes non satisfaites des bogues dans vos tests, et vous avez la possibilité d'ajouter un message personnalisé qui sera affiché dans la sortie de votre test. Une sortie de test bien formulée peut vous aider à localiser les erreurs dans votre code qui ont provoqué l'échec d'un test.

Je pense qu'il est valable d'ajouter des tests pour s'assurer que votre code ne lève pas d'exceptions ; par exemple, imaginez que vous validez une entrée et que vous devez convertir une chaîne entrante en un long. Il peut arriver que la chaîne soit nulle, ce qui est acceptable, et vous voulez donc vous assurer que la conversion de la chaîne ne lève pas d'exception. Il y aura donc du code pour gérer cette occasion, et si vous n'avez pas écrit de test pour cela, vous manquerez la couverture d'un élément important de la logique.

10voto

JJS Points 1345

Cette classe d'aide m'a permis d'atteindre mon objectif avec MSTest. Peut-être qu'il peut aussi gratter la vôtre.

[TestMethod]
public void ScheduleItsIneligibilityJob_HasValid_CronSchedule()
{
    // Arrange
    var factory = new StdSchedulerFactory();
    IScheduler scheduler = factory.GetScheduler();

    // Assert
    AssertEx.NoExceptionThrown<FormatException>(() =>
        // Act
        _service.ScheduleJob(scheduler)
    );
}

public sealed class AssertEx
{
    public static void NoExceptionThrown<T>(Action a) where T:Exception
    {
        try
        {
            a();
        }
        catch (T)
        {
            Assert.Fail("Expected no {0} to be thrown", typeof(T).Name);
        }
    }
}

0 votes

@Remco Beurskens - l'ajout d'un catch { } général à la fin de NoExceptionThrown<T> supprimera les autres erreurs, ce qui n'est pas une conséquence prévue de la méthode. Ce n'est pas une méthode à usage général pour supprimer toutes les exceptions. Elle est destinée à échouer uniquement lorsqu'une exception du type connu est déclenchée.

2 votes

C'est super vieux maintenant, mais Assert a un accesseur de propriété singleton, That que l'on peut utiliser comme un crochet pour les méthodes d'extension. Il pourrait être plus propre, et plus facile à découvrir, de disposer de Assert.That.DoesNotThrow() plutôt que AssertEx.DoesNotThrow() . Ce n'est qu'une opinion.

9voto

jimmy_keen Points 14831

Ne testez pas que quelque chose ne se produit pas . C'est comme s'assurer que le code ne se casse pas . C'est en quelque sorte implicite, nous nous efforçons tous de créer un code sans faille et sans bogue. Vous voulez écrire des tests pour ça ? Pourquoi juste une méthode ? Ne voulez-vous pas que l'on teste toutes vos méthodes pour vérifier qu'elles ne lance pas d'exception ? En suivant cette voie, vous vous retrouverez avec un test supplémentaire, factice, sans affirmation. pour chaque méthode de votre base de code. Cela n'apporte aucune valeur.

Bien sûr, si votre besoin est de vérifier la méthode fait attraper les exceptions vous devez tester cela (ou inverser un peu les choses ; tester qu'il ne lance pas ce qu'il est censé attraper).

Cependant, l'approche et les pratiques générales restent intactes - vous n'écrivez pas de tests pour des exigences artificielles/ vagues qui sont hors de la portée du code testé (et tester que "ça marche" ou "ça ne jette pas" en est généralement un exemple - surtout dans un scénario où les responsabilités de la méthode sont bien connues).

Pour faire simple - concentrez-vous sur ce que votre code doit faire et de tester pour cela.

4voto

jdl134679 Points 1363

J'aime voir un Assert.Whatever à la fin de chaque test, juste pour la cohérence... sans cela, puis-je vraiment être sûr qu'il n'est pas censé y en avoir un ?

Pour moi, c'est aussi simple que de mettre Assert.IsTrue(true);

I connaître Je ne l'ai pas fait. accidentellement a mis ce code là, et donc je devrais être assez confiant après un rapide survol que c'était comme prévu.

    [TestMethod]
    public void ProjectRejectsGappedVersioningByDefault() {

        var files = new List<ScriptFile>();
        files.Add(ScriptProjectTestMocks.GetVersion1to2());
        files.Add(ScriptProjectTestMocks.GetVersion3to4());

        Assert.Throws<ScriptProject.InvalidProjectFormatException>(() => {
            var sut = new ScriptProject(files);
        });

    }

    [TestMethod]
    public void ProjectAcceptsGappedVersionsExplicitly() {

        var files = new List<ScriptFile>();
        files.Add(ScriptProjectTestMocks.GetVersion1to2());
        files.Add(ScriptProjectTestMocks.GetVersion3to4());

        var sut = new ScriptProject(files, true);

        Assert.IsTrue(true);   // Assert.Pass() would be nicer... build it in if you like

    }

0 votes

Ce n'est pas la même chose. Si votre code se lance, aucune assertion ne sera trouvée et votre test échouera. Vous voulez vous connecter au cadre de test en affirmant une condition.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X