10
votes

Comment tester le motif de référentiel avec ADO.NET Entity Framework?

Lors de l'utilisation de motif de référentiel, je trouve qu'il est difficile de comprendre la raison de la conception du logiciel avec TDD Technique, tandis que vous devrez mettre en œuvre l'interface de votre référentiel de votre jeu de données de persistance.

Pour faire clairement le point que je vais Soumettre un exemple:

J'ai l'interface suivante sur mon modèle de domaine: xxx

J'ai la mise en œuvre suivante de l'interface à des fins de test: xxx

maintenant je crée quelques tests:

  1. CAN_ADD_USER
  2. can_add_account pour un utilisateur
  3. CAN_ADD_SHARESPACE Pour un compte d'un utilisateur avec un autre utilisateur.

    Ma question est, après avoir testé toutes ces personnes avec ma mise en œuvre de FakeUserEroppository, je dois revenir en arrière et mettre en œuvre l'iSERREPOSITOIRE de mon jeu de données de persistance réelle (IG SQL), et je dois mettre en œuvre à nouveau le code, donc Mon test de l'unité ne vérifie pas réellement le code que j'utilise réellement sur mon application.

    Peut-être que je manque quelque chose.

    merci comme toujours!

    ci-dessous! Ensuite, mon référentiel d'accès à des données persistantes qui est censé être soumis à un test (par mon esprit au moins), mais je ne devrais ensuite pas tester accroché à la base de données: xxx


0 commentaires

3 Réponses :


3
votes

Vous devez tester la classe réelle et non un faux que vous faites pour tester. Le point d'utiliser une interface est qu'il vous permet de vous moquer de la classe. Vous pouvez ainsi utiliser la version simulée des tests avec d'autres collaborateurs.

Pour tester la classe, vous devriez pouvoir passer dans une base de données simulée et affirmer que les appels que vous devriez être effectués dans la base de données se produisent lorsque vous appelez les méthodes de votre classe de référentiel.

Voici une bonne introduction à la moqueur et aux tests en C #:

http://refact.blogspot.com/2007 /01/mock-Objects-and-rhino.html


0 commentaires

12
votes

Ne jamais tester un simulateur. La classe testée doit toujours être un exemple réel de la classe, bien que vous puissiez et devriez vous moquer de ses dépendances afin que vous puissiez le tester de manière isolée.


4 commentaires

Bonjour TVANFosson: Merci pour la réponse. Je comprends votre message, et c'est la raison pour laquelle j'ai la question. Si je ne devrais pas tester ma fakeimplemérement de l'Iusserpository, je dois, je dois tester la mise en œuvre de SQLUSERPOSITOIRE de IUSERPOSITOIRE, qui est celle que j'utilise. Mais si je le fais, je passe ensuite avec la base de données et j'ai lu que cela devrait être évité. Je sais que je manque quelque chose pour faire la connexion, je ne sais tout simplement pas ce que c'est. Merci.


@Geo: En testant le SQLRepository réel, vous êtes déjà dans l'intégration-test Terre .. Pour un test d'unité, le test ne teste pas du tout, le SQLRepository est totalement valide.


Je triche. Mes référentiels sont en réalité annexés par un contexte de données LINQ. Je me moque du contexte de données LINQ lors du test du référentiel. Je ne termine pas l'unité testant le contexte de données car il est généré du code. Vous aurez besoin de quelques tests d'intégration, cependant, si vous allez ce itinéraire - vous le feriez quand même, non? - Parce que Linq to SQL se comporte différemment de Linq aux objets (la version simulée).


Cette réponse ne répond pas à la question et confirme simplement ce que @geo a demandé. S'il vous plaît fournir un exemple



5
votes

Je vais expliquer ce que je fais, pourquoi et combien de milioliers je le sors.

Tout d'abord, je vais exactement ce que vous faites, en ce qui concerne vos référentiels. Malgré certaines différences d'espace de noms, c'est ce que je fais aussi:

  • myProject.repositories.Iuserepository
  • myProject.repositories.fake.userePository
  • myProject.repositories.sqlserver.userepository

    avec mon faux userpiository, je ne crée pas simplement et peupler un iEnumerable privé collection (qui est une liste ). Pourquoi ai-je cela? J'utilise ce référentiel pour mon initial Développement quotidien (car il est rapide -> Aucun accès DB == Quick!). Ensuite, je échange des faux révisions pour les référentiels SQL (c.-à-d. Monsieur mon injection de dépendance (Oooohhh!)). C'est pourquoi cette classe / espace de noms existe, par opposition à l'utilisation de maquillages dans mon test de l'unité pour «faux» trucs. (Cela se produit, mais dans des circonstances différentes).

    avec mon utilisateur SQL Server userpositity, j'utilise Linqtosql. En ce qui concerne votre question, il est irrélivant que j'utilise Linqtosql ... cela pourrait être n'importe quel autre emballage de base de données. La chose importante ici est qu'il y a une tierce partie quelque chose que je suis l'intégration avec.


    OK, donc d'ici, j'ai besoin de Pour vous assurer de deux choses

    1. le faux fonctionne d'userrypostitaire
    2. L'utilisateur SQL Server UseRePository fonctionne.

      Tout d'abord, la plupart des gens ne créent pas de test unitaire pour une fausse chose. C'est un faux morceau de turd, alors pourquoi gaspiller l'énergie? VRAI --- Sauf que j'utilise ce faux morceau de la Tombe dans mon développement quotidien (voir My Blarg à ce sujet ci-dessus). Donc, je préparais rapidement quelques tests d'unités de base. Remarque: dans mes yeux Ce sont des tests unitaires, même s'ils sont Repository classes. Pourquoi? Ils ne sont pas intermédiaires avec une tierce partie / infrastructure.

      Suivant (enfin, je vais au point), je fais une classe de test séparée qui est un test d'interrogation. Ceci est un test unitaire qui interdire avec quelque chose en dehors du système. Ce pourrait être la vraie API Twitter. Ce pourrait être la vraie API Amazon S3. Avis que j'ai utilisé le mot réel . C'est la clé, ici. Je m'interroge avec un vrai service en dehors de la mienne. Comme tel -> c'est lent. Chaque fois que j'ai besoin de quitter mon ordinateur pour certaines données, il s'appelle Intergratiser et vous supposez automatiquement (et attendez-vous) pour être lent.

      Alors ici, je m'interroge avec un Base de données.

      (Sayers Nae, veuillez ne pas troll ceci avec des suggestions effrontés que vous avez la base de données sur le même ordinateur ... Vous laissez votre application 'World'). < p> wow. Ceci est un roman de guerre-N-N-Paix .. Temps pour une action difficile, Cock Slappin Code. Permet de l'apporter! xxx

      OK, passons à travers ce chiot.

      Tout d'abord, il utilise le test de l'unité Microsoft - intégré à VS2010 Beta2 ou avec L'édition de la Fondation de l'équipe de VS2008 (ou quelle que soit la version de la version ... Je viens d'installer la copie Notre travail a acheté).

      Deuxièmement, chaque fois que la classe est initialisée (que ce soit un test ou plusieurs), Cela crée le contexte . Dans mon cas, mon utilisateur SQL Server UseRePository qui utilisera un contexte LINQTOSQL. (Le vôtre sera un contexte EF). C'est le Arrangez partie de TDD.

      troisième, j'appelle la méthode -> Ceci est la acte partie de TDD. < P> Enfin, je vérifie si je suis revenu ce que je m'attendais - c'est le affirmer partie de TDD.


      Qu'en est-il de la mise à jour de la DB?

      Suivez simplement le même motif, sauf que vous souhaiterez peut-être envelopper votre code d'appel dans une transaction et le rouleau. Sinon, vous pourriez avoir 100 rangs de données pouvant éventuellement être identiques. Inconvénient à cela? Les champs identité n'auront pas toute la séquence de numérotation agréable (Becuase the Rollback "utiliser" "utiliser". Ne fait pas de la sens? ne t'inquiète pas. C'est un conseil avancé, je pensais que j'avais lancé pour vous tester, mais cela signifie que je serais accrocheur pour ce post enferment long.


      SO .. er .. c'est ce que je fais. Je ne sais pas si les dieux de la programmation, sur ces forums, vont basculer et jeter de la boue mon chemin, mais j'espère que cela pourrait vous aider.

      htH. < / p>


2 commentaires

"InitializizedServertestSdata" ne devient pas très difficile à manier lorsque vous avez un graphique d'objet complexe? Comment expliquez-vous le fait que les tests à des niveaux plus élevés nécessiteront différentes données de test? par exemple. Quelques utilisateurs inactifs, certains utilisateurs en retard, aucun utilisateur, utilisateurs de la société A, etc.


Pas sûr @betitall - c'était trop longtemps maintenant. Et je suis passé de ça. C'est tout ravençant pour moi maintenant :) pour SQLServer, j'ai abandonné l'unité le testant et faisons semblant de nos dB. beaucoup pita.