Nous avons l'objet
public class MyObject{
protected MyObject(){}
public string Property1 {get;private set;}
public string Property2 {get;private set;}
public string Property3 {get;private set;}
public string Property4 {get;private set;}
public string Property5 {get;private set;}
public string Property6 {get;private set;}
public string Property7 {get;private set;}
public string Property8 {get;private set;}
public string Property9 {get;private set;}
public string Property10 {get;private set;}
}
Dans notre code de production, nous remplissons cet objet par le biais de MOWORAPPER. Il peut accéder aux propriétés et les définir correctement.
Maintenant, lorsque nous voulons tester cette classe dans un futur pipeline, il n'est pas possible de remplir les propriétés avec des valeurs factices (à tester).
Il y a quelques options disponibles.
Constructeurs personnalisés Pour accepter les paramètres requis pour les tests et définir les propriétés, 3 constructeurs sont actuellement nécessaires. Ce n'est pas propre car les constructeurs ne servent aucune fonctionnalité d'entreprise.
Faites les propriétés virtuelles afin que la classe puisse être talonnée. Mais marquer les propriétés virtuelles ne fournit aucune valeur commerciale et pollue ma classe.
Ajoutez un constructeur d'objets à la classe pour construire à l'intérieur de l'objet. À nouveau aucune valeur commerciale ajoutée. Peut-être un peu plus propre mais toujours beaucoup de code non pertinent dans les objets de domaine.
Des suggestions, des conseils ou des options alternatives ici?
Vous avez plusieurs options.
Allez-y et utilisez des constructeurs personnalisés, des propriétés virtuelles ou un constructeur d'objets. La justification derrière ceci est qu'un objet devrait se tenir seul et ne dépend pas de la magie comme la Massifuteur. Une classe qui est complètement inutile, à moins que la magie ne se passe-t-elle n'est pas une très bien pensée de la classe. "Valeur commerciale" n'est pas le seul déterminant d'un bon design.
Inclure la FadifPER dans le processus de test. Certains diront que ce n'est plus un test unitaire. Cela n'a pas d'importance. Le test de l'unité n'est pas le uniquement type de test.
Implémenter quelque chose qui fournit la fonctionnalité de Spécificatif spécifiquement pour les tests. Vous pouvez facilement écrire un petit utilitaire qui utilisera la réflexion pour renseigner votre objet à partir d'un dictionnaire contenant des noms de propriété et des valeurs.
Regardez également cette question et cette réponse: Voulez-vous plutôt faire des trucs privés internes/publics pour des tests ou utiliser une sorte de piratage comme privéObject?
Je n'hésite pas à utiliser la réflexion pour des choses comme celle-ci dans les tests.
Je n'aime pas faire de choses virtuelles pour se moquer car elle modifie le code de la mauvaise raison.
Je ne connais pas la consomapper mais je suis d'accord avec @mike qui y compris dans les tests peut être une bonne idée. Le test de test d'unité de distinction/d'intégration n'est pas très intéressant IMO. Bien sûr, si la suite de test devient grosse et lente, vous devrez filtrer et classer les éléments pour exécuter uniquement un sous-ensemble sensible de tous tests à la fréquence la plus élevée.
Exemple de hack à l'aide de la réflexion, à l'aide de NameOf () aura mieux perf, mais alors vous perdez des types.:
public static class TestExtensions
{
public static void SetProperty<TSource, TProperty>(
this TSource source,
Expression<Func<TSource, TProperty>> prop,
TProperty value)
{
var propertyInfo = (PropertyInfo)((MemberExpression)prop.Body).Member;
propertyInfo.SetValue(source, value);
}
}
Pour des tests d'unités, utilisez des cadres moqueurs tels que Microsoft Fakes, Typemock et JustMock, qui permet de soutenir des membres privés moqueurs.
Veuillez consulter également les SMOCKS (Packages AVAIBLE @NUGET). La limitation des smocks est, elle ne donnera pas accès aux membres privés. Mais il a la capacité de se moquer de membres statiques et non virtuels. En outre, il est disponible gratuitement.
Un autre moyen le plus simple est d'utiliser, privéobject/privateType.