-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TDD / BDD newbie question regarding the use of stubs... #2
Comments
Hi, thanks for the questions! Like everything else in life, this is a trade-off so I'm not going to pretend there's a right answer. Using real objects rather than doubles:
In general I find using concrete Value Objects in tests makes sense (we don't double other values like integers or strings, after all). It tends to lead to more readable tests and when a VO is broken it's been, in my experience, easy to see what the problem is even though many tests fail as a result. I wouldn't restrict the approach to value objects either; a lot of the time when I am doubling a concrete class I stop and think about whether it would make more sense to either:
More and more I'm finding that one of these solutions seems better; either the class is connected to infrastructure or some other bounded context that should be isolated anyway, or is trivial enough to use directly. This is something I'm constantly trying to evaluate as I do it, and my advice may well be different in a couple of years of doing it, but that's where I am right now. The main thing is to try to make the tests very clear for others, without making it too hard to debug failures. Hope this helped? |
As @ciaranmcnulty asked me to post this:
|
Yeah that's a good point I didn't mention. There are many reasons for using Doubles:
None of these really apply to Value Objects except 1, which is why I focussed there, but it's worth mentioning the other reasons. |
Does using doubles instead of concrete instances of a value object really lead to a better test isolation though? For me one of the disadvantages of not doubling a value object is that sometimes I have value objects which depend on other VOs and those VOs might also depend on other VOs. It can get quite tedious and annoying to write tests for such use cases since you have to build each value object separately. |
@MarkRedeman In the simple case that if the VO breaks lots of tests break. That's all really. I agree about construction of VOs getting tricky but then it will be tricky to construct them in your real code too - it can be solved using the various creational design patterns (I tend to like Builders) |
Even if you wanted, you couldn't mock Values Objects because they are |
In this case, but there's no requirement for a VO to be |
@ciaranmcnulty Thank you very much for the explanation! :) |
In a traditional London school sense, the primary reason for using doubles is to help you design communication between objects by exposing it. If assertions is the way to put design pressure on objects themselves, doubles is the way to put design pressure on their interactions. My rule of thumb for all doubles is - use them when you care about the object collaboration. I find that I rarely care about collaboration with Value Objects, Collections and other simple value representations. |
Hello,
I'm learning TDD / BDD / DDD and I was using your presentation (which I had the opportunity to see live by the way) as a tutorial (in the sense of going through each slide and typing and doing it on my machine).
I was wondering and would like to ask you why you don't use stubs in certain specs.
For example, for the origin and destination airports in the RouteSpec and why not defining what they will return like this:
instead of:
I'm green at TDD / BDD and I read and heard that it's best to use doubles for dependencies, that's why I was surprised to see that you instantiate the Airport value objects here.
Is it because they're value objects that you decided to use those dependencies in the Route spec?
I also noticed something similar (or at least it looks like so to me) but for a more complex case in the TicketIssuerSpec:
Doesn't this make the tests / specs more fragile?
Thank you very much for your presentation showing the process step by step and for putting the code too, I've learned a lot from it!
Take good care,
Hubert
PS: I didn't know where to ask about the code so I created an issue (even if it is not really an issue, except maybe for me having an issue with understanding those things... ;) ). Hope it's OK for you.
The text was updated successfully, but these errors were encountered: