Quelle est la meilleure façon de tester unitaire une méthode qui ne renvoie rien? Plus précisément en c #.
Ce que j'essaie vraiment de tester, c'est une méthode qui prend un fichier journal et l'analyse pour des chaînes spécifiques. Les chaînes sont ensuite insérées dans une base de données. Rien qui n'ait été fait auparavant mais étant TRÈS nouveau dans TDD Je me demande s'il est possible de tester ceci ou est-ce quelque chose qui n'est pas vraiment testé.
c#
unit-testing
jdiaz
la source
la source
Réponses:
Si une méthode ne renvoie rien, il s'agit de l'un des éléments suivants
Méthodes impératives - vous pouvez vérifier si la tâche a été réellement effectuée. Vérifiez si le changement d'état a effectivement eu lieu. par exemple
peut être testé en vérifiant si le solde posté ce message est bien inférieur à la valeur initiale par dAmount
Méthodes informationnelles - sont rares en tant que membre de l'interface publique de l'objet ... donc normalement pas testées à l'unité. Cependant, si vous le devez, vous pouvez vérifier si le traitement à effectuer sur une notification a lieu. par exemple
peut être testé en vérifiant si l'e-mail est envoyé
Publiez plus de détails sur votre méthode actuelle et les gens pourront mieux répondre.
Mise à jour : votre méthode fait 2 choses. Je l'ai en fait divisé en deux méthodes qui peuvent maintenant être testées indépendamment.
String [] peut être facilement vérifié en fournissant à la première méthode un fichier factice et les chaînes attendues. Le second est un peu délicat ... vous pouvez soit utiliser un Mock (google ou search stackoverflow sur des frameworks moqueurs) pour imiter la DB ou frapper la DB réelle et vérifier si les chaînes ont été insérées au bon endroit. Vérifiez ce fil pour quelques bons livres ... Je recommanderais Pragmatic Unit Testing si vous êtes dans une crise.
Dans le code, il serait utilisé comme
la source
Testez ses effets secondaires. Ceci comprend:
Bien sûr, il y a une limite à bien vous pouvez tester. Vous ne pouvez généralement pas tester avec toutes les entrées possibles, par exemple. Testez de manière pragmatique - suffisamment pour vous donner l'assurance que votre code est conçu de manière appropriée et mis en œuvre correctement, et suffisamment pour servir de documentation supplémentaire pour ce à quoi un appelant peut s'attendre.
la source
Comme toujours: testez ce que la méthode est censée faire!
Devrait-il changer l'état global (euh, odeur de code!) Quelque part?
Doit-il faire appel à une interface?
Doit-il lever une exception lorsqu'il est appelé avec les mauvais paramètres?
Ne devrait-il lever aucune exception lorsqu'il est appelé avec les bons paramètres?
Devrait-il ...?
la source
Les types de retour / sous-programmes annulés sont de vieilles nouvelles. Je n'ai pas fait de type de retour Void (sauf si j'étais extrêmement paresseux) depuis 8 ans (à partir du moment où cette réponse, donc juste un peu avant que cette question ne soit posée).
Au lieu d'une méthode comme:
Créez une méthode qui suit le paradigme int.TryParse () de Microsoft:
Peut-être qu'il n'y a aucune information que votre méthode a besoin de renvoyer pour une utilisation à long terme, mais renvoyer l'état de la méthode après qu'elle a effectué son travail est une grande utilité pour l'appelant.
De plus, bool n'est pas le seul type d'état. Il y a un certain nombre de fois où un sous-programme créé précédemment peut en fait retourner trois ou plusieurs états différents (bon, normal, mauvais, etc.). Dans ces cas, vous utiliseriez simplement
Cependant, bien que Try-Paradigm réponde quelque peu à cette question sur la façon de tester un retour nul, il y a aussi d'autres considérations. Par exemple, pendant / après un cycle «TDD», vous seriez «Refactoring» et vous remarquerez que vous faites deux choses avec votre méthode… brisant ainsi le «principe de responsabilité unique». Cela devrait donc être réglé en premier. Deuxièmement, vous avez peut-être identifié une dépendance ... vous touchez des données «persistantes».
Si vous effectuez les tâches d'accès aux données dans la méthode en question, vous devez refactoriser dans une architecture à n niveaux ou à n couches. Mais nous pouvons supposer que lorsque vous dites "Les chaînes sont ensuite insérées dans une base de données", vous voulez en fait dire que vous appelez une couche de logique métier ou quelque chose du genre. Ya, nous supposerons que.
Lorsque votre objet est instancié, vous comprenez maintenant que votre objet a des dépendances. C'est à ce moment que vous devez décider si vous allez effectuer une injection de dépendances sur l'objet ou sur la méthode. Cela signifie que votre constructeur ou la méthode en question a besoin d'un nouveau paramètre:
Maintenant que vous pouvez accepter une interface de votre objet de niveau métier / données, vous pouvez la simuler pendant les tests unitaires et ne pas avoir de dépendances ni de craindre les tests d'intégration «accidentels».
Donc, dans votre code en direct, vous passez un
IBusinessDataEtc
objet REAL . Mais dans vos tests unitaires, vous passez unIBusinessDataEtc
objet MOCK . Dans cette maquette, vous pouvez inclure des propriétés non-interface commeint XMethodWasCalledCount
ou quelque chose dont le ou les états sont mis à jour lorsque les méthodes d'interface sont appelées.Ainsi, votre test unitaire passera par votre (vos) méthode (s) en question, exécutera la logique dont ils disposent et appellera une ou deux, ou un ensemble sélectionné de méthodes dans votre
IBusinessDataEtc
objet. Lorsque vous faites vos assertions à la fin de votre test unitaire, vous avez maintenant deux ou trois choses à tester.IBusinessDataEtc
objet Mock .Pour plus d'informations sur les idées d'injection de dépendances au niveau de la construction ... en ce qui concerne les tests unitaires ... consultez les modèles de conception de Builder. Il ajoute une interface et une classe de plus pour chaque interface / classe actuelle que vous avez, mais elles sont très minuscules et fournissent d'énormes augmentations de fonctionnalités pour de meilleurs tests unitaires.
la source
public void sendEmailToCustomer() throws UndeliveredMailException
?void
méthodes, en particulier dans les langages orientés objet, cela a été la seule vraie option. La plus ancienne alternative de Microsoft est le Try-Paradigm dont je parle et les paradigmes de style fonctionnel comme Monads / Maybes. Ainsi, les commandes (dans CQS) peuvent toujours renvoyer des informations d'état précieuses au lieu de s'appuyer sur le lancement, ce qui est similaire à unGOTO
(ce que nous savons est mauvais). lancer (et aller) sont lents, difficiles à déboguer et ne sont pas une bonne pratique.Essaye ça:
la source
ExpectedAttribute
est conçu pour rendre ce test plus clair.Vous pouvez même l'essayer de cette façon:
la source
cela aura un certain effet sur un objet ... demande le résultat de l'effet. S'il n'a pas d'effet visible, il ne vaut pas la peine de tester unité!
la source
Vraisemblablement, la méthode fait quelque chose et ne revient pas simplement?
En supposant que c'est le cas, alors:
Si vous nous dites ce que fait la méthode, je pourrais être plus précis.
la source
Utilisez Rhino Mocks pour définir quels appels, actions et exceptions peuvent être attendus. En supposant que vous puissiez vous moquer ou remplacer certaines parties de votre méthode. Difficile à savoir sans connaître ici quelques détails sur la méthode, ni même le contexte.
la source
Cela dépend de ce qu'il fait. S'il a des paramètres, transmettez des simulacres que vous pourrez demander plus tard s'ils ont été appelés avec le bon jeu de paramètres.
la source
Quelle que soit l'instance que vous utilisez pour appeler la méthode void, vous pouvez simplement utiliser,
Verfiy
Par exemple:
Dans mon cas,
_Log
c'est l'instance etLogMessage
la méthode à tester:Les
Verify
levées sont-elles une exception en raison de l'échec de la méthode que le test échouerait?la source