Question

Nous utilisons modèle de constructeur pour générer des données de test. Ces objets de domaine ont des relations entre eux. Nos tests fonctionnels exigent que ces objets soient persistaient.

Pensez à ce modèle:

Si je veux un exemple simple de C je aNew().c().build()

Si je veux qu'il soit persistait je aNew().c().saveIn(session)

Si je veux une instance de C avec un B connu je aNew().c().with(b).build()

Eh bien, vous avez l'idée. Mon problème est, si je veux persister un C, si elle devait persister, il est B? Ou devrait-il être persisté avant la main? Qu'en est-il si je veux un B défaut raisonnable? Qu'en est-il si je veux persister un D? Si elle devait persister tout A, B, C?

Bien sûr, le système réel est beaucoup plus complexe (parfois avec des références circulaires). Je cherche une meilleure pratique pour la persistance des données de test complexes.

Modifier On dirait que je suis tombé sur la barrière de la langue, ma langue maternelle est pas l'anglais, donc je suis désolé pour l'obscurité. Voici plus d'informations:

  • Il est pas le code héritage que je suis en train de tester
  • Je suis en train d'écrire un test de couverture, pas un test unitaire (par conséquent, je ne serai pas rien moquais)
  • Le logiciel que je suis en train de test fonctionne si la base de données est rempli dans une certaine mesure (ne pas utiliser toutes les entités).

PS. S'il vous plaît ne pas hésiter à demander plus d'informations, parce que je me bats pour trouver la meilleure pratique possible. La chose la plus proche, je suis venu avec est:

  1. Gardez une trace de ce qui a été explicitement défini lors de la construction d'une entité.
  2. On suppose que les entités explicitement définies sont déjà persisté, ne les persistent pas.
  3. Persistent tout le reste (avec leur propre persister).

Cela fonctionne, mais mon sens d'araignée est picotement, je pense que je suis en train de faire quelque chose de mal parce que, il y aura une logique impliquée dans le code de test, il sera très complexe à traiter sans tests.

Edit 2: Je vais essayer de me faire plus clair. Quand je suis en train d'écrire / courir mon unité et certains tests d'intégration que j'ai pas de problème, parce que les données de test ne sont pas conservées, il vit dans la mémoire.

Mais quand j'essaie de persister mes données de test, mise en veille prolongée ne me laisse pas enregistrer une entité sans ses relations.

Comment puis-je résoudre ce problème?

Était-ce utile?

La solution

Vous devez définir vos cascades sur le domaine mieux. Si vous ne pouvez pas le tester, comment voulez-vous qu'il se produira dans l'application réelle?

Par exemple:

A -> B: Qui est le propriétaire de cette relation? Voulez-vous ajouter B à A, ou l'inverse? Cela peut être un détail de mise en œuvre où vous pouvez avoir les deux B.SetParent (A) et A.Children.Add (B), et où vous définissez le parent de B à A, en cas de A.Children.Add (B) (également l'autre autour). Qu'advient-il si vous faites:

A a1 = new A();
A a2 = new A();
B b = new B();
a1.Children.Add(b);
b.SetParent(a);

Vous devez faire ici votre esprit. Aucune des solutions sont parfaites, il est donc fondamentalement préférence personnelle et la cohérence de l'application qui s'applique ici.

Travailler avec ORM vous entrez dans ces problèmes de contrainte plus rapide puis avec SQL ordinaire (ou tout autre source de données comme XML ou votre propre source de données), mais vous auriez besoin d'examiner les problèmes si vous deviez écrire trop SQL ordinaire.

Je suis désolé, je n'ai pas une réponse définitive pour vous, mais pour moi, il semble que vous devez prendre en compte certaines contraintes (je suppose) que vous ne l'avez pas encore fait.

Personnellement, j'aime le dépôt-modèle en traitant en utilisant NHibernate dans LAD. Je fais mes dépôts de mettre en œuvre IDisposable et laissez-les faire une session chacun. De cette façon, vous obtenez la « unité de travail » -pattern dans votre conception.

Bonne chance avec elle:)

Autres conseils

Vous devriez probablement décrire votre configuration de test plus en détail. En particulier, pourquoi faire passer vos tests fonctionnels ont besoin de ces objets à persista? Etes-vous tester le fonctionnement de la persistance réelle? Ou est-ce juste un effet secondaire de l'exécution des tests? Voulez-vous charger des objets persistaient dans le cadre de vos tests?

  

Mon problème est, si je veux persister un C, si elle devait persister, il est B? Ou devrait-il être persisté avant la main?

Cela dépendra de la raison pour laquelle vous persistez en premier lieu. Si vous êtes intégration tester la couche de persistance, alors vous devriez simplement utiliser la logique de l'application elle-même utilise. Si c'est juste un effet secondaire des tests, vous voudrez peut-être se moquer de la couche de persistance, etc ...

Je choisis vos réponses par sujet.

  

Mon problème est, si je veux persister un C , si elle devait persister, il est B ? Qu'en est-il si je veux persister un D? Si elle devait persister tout A, B, C?

Ceci est entièrement tributaire des contraintes de domaine que vous choisissez de faire respecter. Par exemple, est C une entité et un objet de valeur B ? En d'autres termes, le fait C ont une identité unique et la vie de son propre? B principalement identifié par sa valeur et son cycle de vie étroitement couplée à celle de son parent C ?

Demander ces types de questions devraient aider à guider vos décisions sur ce qu'il faut persister, quand et par qui.

Par exemple, si les deux C et B sont des entités qui partagent seulement une relation, vous pouvez décider de les persister indépendamment, car chacun pourrait imaginer avoir une vie pleine de sens et de l'identité de sa propre. Si B est un objet de valeur, vous choisiriez probablement avoir son entité mère C contrôler sa vie, y compris la création / récupération / mise à jour / suppression de l'objet. Cela pourrait inclure très bien C persistant B .

  

Ou faut-il persistait avant la main?

Pour répondre à cela, vous pourriez avoir à tracer vos dépendances. Ces dépendances sont souvent représentées par des contraintes clés étrangères lorsqu'un objet graphique est conservé à un SGBDR. Si C ne pourrait pas fonctionner sans une référence à B , alors vous voudrez probablement les persister à la fois dans une transaction, avec B se fait en premier de se conformer aux contraintes clés étrangères de la base de données. En suivant la ligne de la pensée ci-dessus, si B était une entité enfant ou objet de valeur de C , vous pourriez même avoir C responsable de la persistance B .

  

Qu'en est-il si je veux un B défaut raisonnable?

La création de B les instances pourrait être déléguée à B -Factory. Que vous mettre en œuvre cette logique d'usine comme méthode, constructeur, ou séparez comme sa propre unité de classe (non par exemple) n'a pas d'importance. Le point est que vous avez un endroit où la création et la configuration des nouvelles B s a lieu. Il est à cet endroit que vous auriez une configuration par défaut de l'objet ont lieu nouvellement instancié.

Une excellente ressource qui couvre ce genre de questions est Domain-Driven Design par Eric Evans

Je ne suis pas sûr d'avoir compris le problème que vous essayez de résoudre très bien, mais ... Qu'en est-sérialisation tout le graphique en XML en utilisant quelque chose comme XStream ou Google Protocol Buffers ?

  • Qu'est-ce que vos tests vous dit?
  • Il semble que votre test d'une application héritée?
  • Donc, votre fonctionnalité prend déjà écrit dans votre base de code et d'essayer de créer un test de couverture?

Donnez-nous plus de commentaires s'il vous plaît

Pour autant que je le vois le problème est avec votre domaine (comme vous l'avez dessiné). Pour autant que j'understanf C, il a une relation de plusieurs à l'un à B, et la base de données est enfocing par un champ de clé étrangère non annulable. D'autre part du code dans la question que je pouvais comprendre qu'il n'y a pas enforcemnt de la règle exactement un dans le code, et le membre qui fait référence par exemple B dans l'instance C peut être nulle. Pour autant que je comprends le modèle de domaine doit être toujours correct dans le code et l'exécution, donc si cette règle aurait été appliquée dans le code (en exigeant une référence B dans la méthode de construction C () par exemple) vous n'auriez pas tout problème avec persistence - vous pourriez simplement persister tout.

Autre solution beaucoup plus sale serait juste baisse par programme toutes les contraintes DB qui mess avec vos tests avant le test et les restaurer par la suite. Bien sûr, il rendrait la DB complètement inutilisable fot quoi que ce soit en cours d'exécution d'autre dans paralléle à l'épreuve, mais cela peut être résolu en utilisant un interated DB tels que SQLite ou SQL Server Compact Edition juste pour les tests.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top