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:
public void SendEmailToCustomer()
Créez une méthode qui suit le paradigme int.TryParse () de Microsoft:
public bool TrySendEmailToCustomer()
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
public StateEnum TrySendEmailToCustomer()
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:
public <Constructor/MethodName> (IBusinessDataEtc otherLayerOrTierObject, string[] stuffToInsert)
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 un IBusinessDataEtc
objet MOCK . Dans cette maquette, vous pouvez inclure des propriétés non-interface comme int 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.
- L'état du «sous-programme» qui est maintenant une méthode Try-Paradigm.
- L'état de votre
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.