Growing Object-Oriented Software, Guided by Tests Without Mocks

263 views
Skip to first unread message

philip schwarz

unread,
Aug 6, 2016, 4:50:55 PM8/6/16
to Growing Object-Oriented Software
Just bumped into this: http://enterprisecraftsmanship.com/2016/07/05/growing-object-oriented-software-guided-by-tests-without-mocks/

From the first part of the post: 

"So here I’ll take the most canonical example of using mocks I could find – the one from the GOOS book – and will show how the use of mocks damages the design. I’ll also show how much simpler the code base becomes when you get rid of mocks and apply the guidelines I described in the previous posts of this series."

"Despite all the great tips and techniques the book proposes, the amount of potentially harmful advice is quite substantial as well.

The book is a strong proponent of the collaboration verification style of unit testing even when it comes to communication between individual objects inside the domain model. In my opinion, it’s the main shortcoming of the book. All other shortcomings flow from this one.

To justify this approach, the authors allude to the definition of Object-Oriented Design given by Alan Kay:

“The big idea is “messaging” […] The key in making great and growable systems is
much more to design how its modules communicate rather than what their internal
properties and behaviors should be.”

They then conclude that interactions between objects is what you should focus on foremost in unit tests. By this logic, the communication pattern between classes is what essentially comprises the system and identifies its behavior.

There are two problems with this viewpoint. First, I wouldn’t bring the Alan Key’s definition of OOD here. It’s quite vague to build such a strong argument upon and has little to do with how modern strongly-typed OOP languages look like today.

Here’s another famous quote of him:

“I made up the term ‘object-oriented’, and I can tell you I didn’t have C++ in mind”.

And of course, you can safely substitute C++ with C# or Java here.

The second problem with this line of thinking is that separate classes are too fine-grained to treat them as independent communication agents. The communication pattern between them tend to change often and has little correlation with the end result we should aim at verifying.

As I mentioned in the previous post, the way classes inside the domain model talk to each other is an implementation detail. The communication pattern only becomes part of API when it crosses the boundary of the system: when your domain model starts interacting with external services. Unfortunately, the book doesn’t make this distinction.

The drawbacks of the approach the book proposes become vivid when you consider the sample project it goes through in the 3rd part. Not only focusing on collaboration between classes entails fragile unit tests that couple to the SUT’s implementation details, but it also leads to an overcomplicated design with circular dependencies, header interfaces, and an excessive number of layers of indirection."

Philip

David Denton

unread,
Aug 7, 2016, 8:30:10 AM8/7/16
to Growing Object-Oriented Software
Regardless of the argument around the usages of header interfaces or mocks, this article should really have been titled:
 
"Here's some code I checked in a single commit after looking at a pre-existing solution, without any of that tedious 'Growing software' marlarky"

Whilst the author has some perfectly reasonable opinions IMHO, this article is simply missing the point by just showing the finalised state of the code.

/david

Steve Freeman

unread,
Aug 7, 2016, 9:24:05 AM8/7/16
to growing-object-o...@googlegroups.com
Or, perhaps, this isn't a code style I'm familiar with (having come from .Net), so it must be rubbish.

For the record, there are /no/ circular dependencies in the code.

S

Raoul Duke

unread,
Aug 7, 2016, 12:28:39 PM8/7/16
to growing-object-o...@googlegroups.com

There's right and wrong in everything. It would be nice to figure out what are nuggets of food for thought.

For example, I am also pretty wary of testing internal collaborations or implementations eg via mocks.

Not that it is right or wrong, but that it has pluses and minuses. (And each of those can get a 5whys, too.)

How could / should we not also think about how we could grow oo software with less 'coupling'?

Reply all
Reply to author
Forward
0 new messages