How to test value objects when they have dependencies?
| Newsgroups | gmane.comp.programming.domain-driven-design |
|---|---|
| Message-ID | <[email protected]> |
**TL;DR**
How do you test a value object in isolation from its dependencies without stubbing or injecting them?
----------
In Misko Hevery's blog post [To “new” or not to “new”…][1] he advocates the following (quoted from the blog post):
> - An Injectable class can ask for other Injectables in its constructor.(Sometimes I refer to Injectables as Service Objects, but
> that term is overloaded.). Injectable can never ask for a non-Injectable (Newable) in its constructor.
> - Newables can ask for other Newables in their constructor, but not for Injectables (Sometimes I refer to Newables as Value Object, but
> again, the term is overloaded)
Now if I have a `Quantity` value object like this:
class Quantity{
$quantity=0;
public function __construct($quantity){
$intValidator = new Zend_Validate_Int();
if(!$intValidator->isValid($quantity)){
throw new Exception("Quantity must be an integer.");
}
$gtValidator = new Zend_Validate_GreaterThan(0);
if(!$gtvalidator->isValid($quantity)){
throw new Exception("Quantity must be greater than zero.");
}
$this->quantity=$quantity;
}
}
My `Quantity` value object depends on at least 2 validators for its proper construction. Normally I would have injected those validators through the constructor, so that I can **stub** them during testing.
However, according to Misko a newable shouldn't ask for injectables in its constructor. Frankly a `Quantity` object that looks like this
`$quantity=new Quantity(1,$intValidator,$gtValidator);` looks really awkward.
Using a dependency injection framework to create a value object is even more awkward. However now my dependencies are hard coded in the `Quantity` constructor and I have no way to alter them if the business logic changes.
How do you design the value object properly for testing and adherence to the separation between injectables and newables?
Notes:
1. This is just a very very simplified example. My real object my have serious logic in it that may use other dependencies as well.
2. I used a PHP example just for illustration. Answers in other languages are appreciated.
[1]: http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/ http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/