9
votes

Test de l'unité et Nibernate?

Je me demande comment déployer cela. J'utilise NHibernate et fluide.

J'ai une classe de domaine comme celle-ci xxx

Ceci semble être la convention lorsqu'il arrête les personnes de la définition et de l'identité C'est généré automatiquement.

Maintenant, le problème vient quand je suis des tests unitaires.

J'ai tout mon code NHibernate dans un repo que je me moque donc de tester ma couche de service . Le problème vient lorsque cela se produit. xxx

ceci devrait renvoyer un objet utilisateur.

donc je veux utiliser MOQ pour faire ce < Pré> xxx

Voici le problème

Je dois faire cet objet utilisateur et le mettre dans la partie de retour.

donc je ferais donc quelque chose comme ça xxx

Mais c'est là que c'est le problème que je dois définir l'ID car je l'utilise plus tard pour faire du linq sur certaines collections (dans la couche de service telle qu'elle est Ne pas frapper mon dB afin de ne pas être dans ma répétition), j'ai donc besoin de le faire définir mais je ne peux pas la mettre parce que c'est un ensemble privé.

Alors, que dois-je faire? Devrais-je simplement supprimer le privé ou y a-t-il une autre manière?


0 commentaires

4 Réponses :


15
votes

Vous pouvez avoir le faux référentiel (code> objet renvoyer un faux utilisateur objet: xxx

Il y a quelques éléments à observer ici :

  1. MOQ ne peut que fausser des fausses membres de classes en béton si elles sont marquées comme virtuel . Cela peut ne pas être applicable dans certains scénarios, auquel cas le seul moyen de simuler un objet via MOQ est la mise en place d'une interface. Dans ce cas, toutefois, la solution fonctionne bien parce que Nibernate impose déjà la même exigence sur les propriétés de l'utilisateur afin de faire des charges paresseux.
  2. avoir de faux objets renvoyant d'autres faits peuvent parfois conduire à des tests d'unités spécifiés. dans ces situations, la construction de modèles d'objets riches composés de talons et de moqueurs se développe jusqu'au point où il devient difficile de Déterminez ce qui est testé exactement, ce qui rend le test propre illisible et difficile à maintenir. Il s'agit d'une pratique de test d'unité parfaitement fine, d'être claire, mais elle doit être utilisée consciemment.

    Ressources associées:


1 commentaires

Merci cela fonctionne parfaitement. Je pourrais avoir des symptômes de numéro 2. Il suffit de se moquer de tellement de choses. J'essaie de le garder aussi seulement ce que j'ai besoin de tester. Par exemple, je ne me moque pas d'un nom d'utilisateur pour l'utilisateur car il n'est pas utilisé dans la méthode. J'aimerais essayer Autofixture MOQ, mais je ne peux pas comprendre comment utiliser vraiment et il semble ne pas y avoir de véritables tutoriels à ce sujet, donc je ne peux pas déterminer si cela m'aiderait ou non.



2
votes

La réponse d'Enrico est sur place pour les tests d'unité. J'offre une autre solution parce que ce problème se cultive également dans d'autres circonstances, où vous ne voudrez peut-être pas utiliser MOQ. J'utilise régulièrement cette technique dans le code de production où le modèle d'utilisation commun est destiné à être en lecture seule, mais certaines autres classes doivent la modifier. Un exemple peut être un champ d'état, qui est normalement en lecture seule et ne doit être défini que par une classe d'état ou une classe logique d'entreprise.

Fondamentalement, vous fournissez un accès au membre privé via une classe imbriquée statique contenant une méthode pour définir. la propriété. Un exemple vaut mille mots: xxx

Vous l'utilisez comme ceci: xxx

bien sûr, cela active ensuite Toute personne à définir la valeur de la propriété presque aussi facilement que si vous aviez fourni un setter public. Mais cette technique présente certains avantages:

  • Aucune invite IntelliSense pour le constructeur de propriétés ou une méthode Seid ()
  • Les programmeurs doivent utiliser explicitement une syntaxe étrange pour définir la propriété avec la classe révéler , ce qui leur poussait à ce qu'ils ne devraient probablement pas faire ce
  • Vous pouvez facilement effectuer une analyse statique sur les usages de la classe pour voir quel code contourne les modèles d'accès standard

    Si vous souhaitez uniquement modifier une propriété privée à des fins de test de l'unité, et que vous êtes en mesure de MOQ, l'objet, alors je recommanderais toujours la suggestion d'Enrico; Mais vous pourriez trouver cette technique utile de temps en temps.


1 commentaires

+1. Beaucoup d'options similaires - InternalsVissibletoatTtribute, protégée et sous-classe, crack avec réflexion, placez dans l'utilisateur sur l'utilisateur avec le texte d'avertissement approprié, passez une carte d'identité sur le constructeur surchargé (ma préférence lorsque cela est possible), etc. J'aime cela parce qu'il encourage le test avec le test Pocos / DTO. Au fur et à mesure que j'aime MOQ, @ Enrico a raison sur les dangers de la spécification excessive.



0
votes

Au lieu d'essayer de vous moquer de votre référentiel, je vous suggère d'essayer d'utiliser une base de données SQLite en mémoire pour les tests. Cela vous donnera la vitesse que vous recherchez et cela facilitera les choses aussi. Si vous souhaitez voir un échantillon de travail, vous pouvez consulter l'un de mes projets GitHub: https://github.com / Dlidstrom / Gridbook .


0 commentaires

2
votes

Une autre alternative Si vous préférez ne pas se moquer de vos classes d'entité consiste à définir l'ID privé / protégé à l'aide de la réflexion.

Oui, je sais que cela n'est généralement pas considéré très favorablement, et souvent cité comme un signe de mauvais design quelque part. Mais dans ce cas, avoir un identifiant protégé sur vos entités NHibernate est le paradigme standard, il semble donc une solution assez raisonnable. P>

Nous pouvons essayer de le mettre en œuvre bien au moins. Dans mon cas, 95% de mes entités utilisent tous un seul guid comme identifiant unique, avec seulement quelques-uns à l'aide d'un entier. Par conséquent, nos classes d'entités implémentent généralement une interface code> très simple code> p> xxx pré>

dans une classe d'entité réelle, nous pourrions l'implémenter comme ceci: p > xxx pré>

Cet identifiant est mappé sur NHibernate comme clé primaire de la manière habituelle. P>

au réglage de celui-ci dans nos tests de l'unité, nous pouvons utiliser cette interface pour fournir une méthode d'extension pratique: p> xxx pré>

Nous ne devons pas avoir l'interface hassid pour le faire, mais cela signifie que nous pouvons sauter un peu de code supplémentaire - par exemple nous N'ayez pas besoin de vérifier si l'identifiant est réellement pris en charge ou non. p>

La méthode d'extension renvoie également l'objet d'origine, donc dans l'usage que je suffisez généralement simplement à la fin du constructeur: P> xxx pré>

ou en fait, car pour les GUID, je ne me soucie pas de ce que l'ID est réellement, j'ai une autre méthode d'extension: p>

var testUser = new User("Test User").WithNewGuid();


0 commentaires