+3  A: 

You should probably describe your test setup in more detail. In particular, why do your functional tests require these objects to be persisted? Are you testing the actual persistence operation? Or is that just a side effect of running the tests? Do you want to load persisted objects as part of your tests?

My problem is, if I want to persist a C, should it persist it's B? Or should it be persisted before hand?

This will depend on why you are persisting in the first place. If you are integration testing the persistence layer, then you should just use the logic the application itself uses. If it's just a side effect of testing, you might want to mock the persistence layer, etc...

sleske
Imagine these data is already existing in the DB. And another process (which I am testing) is reading these data. But sometimes a B is relevant and I want to make it visible in the test while creating and persisting Bs; but sometimes they are not relevant and I am trying to hide them behind builders.
nimcap
That doesn't make sense to me. If the data is already in the DB, why (and whan) do you need to persist it? And what do you mean by "I want to make it [B] visible in the test"??
sleske
A: 
  • What are your tests telling you?
  • It sounds like your testing a legacy application?
  • So your taking functionality already written in your code base and trying to create a coverage test?

Give us some more feedback please

Gutzofter
A: 

I am trying to understand the question. Is the following interpretation correct?

  1. You are searching for an elegant way to create persistent test data
  2. The current persistence mechanism of the application just allows one to save an individual object, not a network of connected objects.
  3. You are worried that the logic for persisting networks ends up in the test code.
  4. You are using the Builder pattern, i.e., have an IBuilder interface, with one or more ConcreteBuilders below it, invoked by a Director in charge of the construction process.

My suggestion then would be to create a new PersistentBuilder implementing the IBuilder interface. This new concrete builder not just builds object structures, but stores them in the database as well. Since the builder knows about the dependencies between the objects it is creating, it can manage assumptions concerning whether or not a given object has been persisted already.

Your actual test code will contain the test-specific Director-code creating the concrete data required for your functional tests.

Since the PersistentBuilder is needed for testing purposes only, I would put it with the rest of the test code in the version control system (e.g., in a separate test utility subtree).

Kaka Woef
+1  A: 

You need to define your cascades on the domain better. If you can't test it, how do you expect it will perform in the real application?

For example:

A -> B: Who's the owner of this relationship? Do you want to add B to A, or the other way around? This can be an implementation detail where you can have both B.SetParent(A) and A.Children.Add(B), and where you set B's parent to A in case of A.Children.Add(B) (likewise the other way around). What happens if you do:

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

You need to make up your mind here. None of the solutions are perfect, so it's basically personal preference and app consistency that applies here.

Working with ORMs you get into these constraint problems faster then with plain SQL (or any other datasource like XML or your own datasource), but you'd need to consider the problems if you were to write plain SQL too.

I'm sorry, I don't have an definite answer for you, but to me it looks like you need to consider some constraints which (I presume) you haven't done yet.

Personally, I like the repository-pattern when dealing using NHibernate in DALs. I make my repositories implement from IDisposable and let them get a session each. This way you get the "Unit of work"-pattern into your design.

Good luck with it :)

cwap
+1  A: 

I separated your answers by topic.

My problem is, if I want to persist a C, should it persist it's B? What about if I want to persist a D? Should it persist all A, B, C?

This is entirely dependent upon the domain constraints you choose to enforce. For example, is C an entity and B a value object? In other words, does C have a unique identity and life of its own? Is B mainly identified by its value and its life cycle tightly coupled to that of its parent C?

Asking these types of questions should help guide your decisions on what to persist, when, and by whom.

For example, if both C and B are entities sharing only a relationship, you might decide to persist them independantly, since each could conceivably have a meaningful life and identity of its own. If B is a value object, you'd probably choose to have its parent entity C control its life, including the creation/retrieval/updating/deleting of the object. This might very well include C persisting B.

Or should it be persisted before hand?

To answer this you could have to map out your object dependencies. These dependencies are frequently represented by foreign key constraints when an object graph is persisted to a RDBMS. If C could not function without a reference to B, then you would probably want to persist them both inside a transaction, with B being done first to comply with the database's foreign key constraints. Following the line of thought above, if B was a child entity or value object of C, you might even have C responsible for persisting B.

What about if I want a reasonable default B?

The creation of B instances could be delegated to the B-Factory. Whether you implement this factory logic as a class (not instance) method, constructor, or separate it out as its own unit doesn't matter. The point is you have one place where the creation and configuration of new Bs takes place. It is in this place that you would have a default configuration of the newly instantiated object take place.

An excellent resource covering these types of questions is Domain-Driven Design by Eric Evans

rcampbell
I could not decide which one to accept, the other one came earlier... so I am sorry, I wish there was a way to accept multiple answers
nimcap
+1  A: 

I'm not sure I understood the problem you are trying to solve very well but... what about serializing the whole graph as XML using something like XStream or Google's Protocol Buffers?

Pascal Thivent
@Pascal Thivent Google protocol buffer added as favorite
Arthur Ronald F D Garcia
A: 

As far as I see it the problem is with your domain (as you've drawn it). As far as i understanf it C has a relationship of many-to-one to B, and the database is enfocing it by a non nullable foreign key field. On the other hand from the code in the question I could understand that there is no enforcemnt of the exactly-one rule in the code, and the member that references B instance in C instance can be null. As far as I understand the domain model should be always correct in code and in run-time, so if this rule would have been enforced in code (by demanding a B reference in C build() method for example) you wouldn't have any problems with persistance - you could just persist all.

Other, much dirtier solution would be just programmatically dropping all the DB constraints that mess with your tests before the test and restoring them afterwards. Of course it would make the DB completely unusable fot anything else running in parralel to the test, but this can be resolved by using an interated DB such as SQLite or SQL Server Compact Edition just for the tests.

RA