Mocks Kill TDD

451 views
Skip to first unread message

philip schwarz

unread,
Nov 3, 2015, 6:58:56 PM11/3/15
to Growing Object-Oriented Software

philip schwarz

unread,
Nov 3, 2015, 7:01:36 PM11/3/15
to Growing Object-Oriented Software
Ron Jeffries blogged: http://ronjeffries.com/articles/015-11/tdd-mocks/

An excerpt:

"Now the London School of TDD concerns itself very much with behavior and relationships. What does the object do? Who does it talk to? What do they say to each other? In what order do they say it? (Remember, if I’m not doing these ideas justice: London School is not my school. This is what I get of it at my current level of experience.)

To a Detroit School TDDer, this attention to relationships and conversations seems almost obsessive. We do concern ourselves with these things, but only rarely. Far more commonly, we send off a message, maybe look at what comes back from it, and remain blissfully ignorant of what goes on behind the scenes."

Philip

philip schwarz

unread,
Nov 3, 2015, 7:03:38 PM11/3/15
to Growing Object-Oriented Software
Keith Braithwaite blogged: http://cumulative-hypotheses.org/2015/11/03/mocks/

A couple of excerpts:

"Mocks were invented to solve a very specific problem: how to test Java objects which do not expose any state. Really not any. No public fields, no public getters."

"That we can do these things with them does not make screwdrivers bad. And the screwdriver does not encourage us to be idiots—it just doesn’t stop us. And so it is with mocks—they are enormously powerful and useful and flexible and will not stop us from being stupid. In particular, they will not stop us from doing out design work badly. And neither with TDD.
What I think they do do, in fact, is make the implementation of bad design conspicuously painful—remember that line about the next test being hard to write? But programmers tend to suffer from very bad target fixation when a tool becomes difficult to use and they put their head down and power through, when they should really stop and take a step back and think about what the hell they’re doing."

Philip

Matteo Vaccari

unread,
Nov 4, 2015, 2:26:51 AM11/4/15
to growing-object-o...@googlegroups.com
On Wed, Nov 4, 2015 at 12:58 AM, philip schwarz <philip.joh...@googlemail.com> wrote:
If this presentation was called "how to rewrite some OO style models to functional style", then it would have hit its target...

It does raise an interesting design point, in the example where it converts a test that says

public testSendEmail() {
  SpecialOffers offers = new SpecialOffers(sender);
  offers.sendSpecialOffers(new Customer(false, “Bob”, “f...@foo.com”));
  verify(sender).send(“f...@foo.com”, new Email(“Hi, Bob!”));
}
to a functional style with

public testSendEmail() {
  SpecialOffers offers = new SpecialOffers();

  SendEmailIntent intent = offers.sendSpecialOffers(new Customer(false, “Bob”, “f...@foo.com”)).get();

  Assert.equals(intent.getAddress(), “f...@foo.com”);
  Assert.equals(intent.getEmail().getText(), “Hi, Bob!”);
}

Now you need to create an "SendEmailIntent" data structure and then an interpreter for it.  The funny thing about OO code is that some data structures can be replaced by behaviour, and this results in less overall code.  It reminds me of this observation by Ivan Moore


about how to solve a logo-turtle programming problem.

My conclusion is that the OO style is a superset of the functional style... by keeping your design options open you may decide to make an intermediate data structure disappear, replacing it with behavour.

Matteo

 

philip schwarz

unread,
Nov 4, 2015, 2:43:44 AM11/4/15
to Growing Object-Oriented Software
Philip

On Tuesday, 3 November 2015 23:58:56 UTC, philip schwarz wrote:

Steve Freeman

unread,
Nov 4, 2015, 3:40:22 AM11/4/15
to growing-object-o...@googlegroups.com
Yep. That article confirms that Ron has no idea what we're talking about and, in fact, has consistently refused to even discuss it. I don't know why. 

If he had read any of out material he would know that we're deeply embedded in Alan Kay's view of the world. 

S

Sent from my iPhone
--

---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriente...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Steve Freeman

unread,
Nov 4, 2015, 3:50:25 AM11/4/15
to growing-object-o...@googlegroups.com
I'm looking forward to the articles in about 5 years time saying that functional is s**t and we should all be using <other thing>. 

I think the ability to flow between object and functional styles, where appropriate, is very powerful. Especially as most everyone is still writing procedural. 

S

Sent from my iPhone
--

Matteo Vaccari

unread,
Nov 4, 2015, 4:33:27 AM11/4/15
to growing-object-o...@googlegroups.com
I think you nail it here Steve: "Especially as most everyone is still writing procedural".

Everywhere you look, it seems you are being pushed to reason starting from the database schema.  To me, data-centric thinking leads to or is the same as procedural thinking.  

For instance, Ruby on Rails is intensely data-centric, where it couples "domain" classes so tightly to the database.  So many smart people are being influenced by Rails, expecially now that the Rails style is widely copied in other platforms (Grails, Play, Zend Framework...) and many programmers are being introduced to it without even realizing that they are using a port of Rails.

As the programming world is getting more and more absorbed by frameworks, and those frameworks generally push for a data-centric view of the world, people tend to assume that OO just means having anaemic domain "objects" with lots of service "objects". 

What can we do?



giancarlo pace

unread,
Nov 4, 2015, 4:52:50 AM11/4/15
to growing-object-o...@googlegroups.com
> I think the ability to flow between object and functional styles, where
> appropriate, is very powerful. Especially as most everyone is still writing
> procedural.

Holy words!

I found my way in developing the core/internal[1] parts of a project
in a more functional style and the adapter/anti-corruption layer more
in an OO style, but it's still a bit qualitative to me.

Have you found any conclusion or idea about how to balance the two styles?
--
gk

[1] let's say algorithmic or computational like a cart total applying
discounts and taxes

Raoul Duke

unread,
Nov 4, 2015, 9:16:25 AM11/4/15
to growing-object-o...@googlegroups.com

+1 :-)

1) Yes, but both FP and OO suck. Most everything sucks, one way or another. But some things suck less in some ways. So FR, FRP, RDP, FBP, etc. are all other interesting paradigms. There's more languages, Horatio.

2) Yes, mostly  everybody is mostly procedural, I live through what you mean daily. :-( Half the time it is due to being lame. The other quarter of the time it is due to having seen some badness of OO.

Steve Freeman

unread,
Nov 5, 2015, 4:23:43 AM11/5/15
to growing-object-o...@googlegroups.com
On 4 Nov 2015, at 09:52, giancarlo pace <giancar...@gmail.com> wrote:
>> I think the ability to flow between object and functional styles, where
>> appropriate, is very powerful. Especially as most everyone is still writing
>> procedural.
>
> Holy words!
>
> I found my way in developing the core/internal[1] parts of a project
> in a more functional style and the adapter/anti-corruption layer more
> in an OO style, but it's still a bit qualitative to me.
>
> Have you found any conclusion or idea about how to balance the two styles?

not really, except trying to keep stuff as local as possible.

S


giancarlo pace

unread,
Nov 5, 2015, 5:32:18 AM11/5/15
to growing-object-o...@googlegroups.com
>> Have you found any conclusion or idea about how to balance the two styles?
>
> not really, except trying to keep stuff as local as possible.

by local you mean stateless/encapsulated ? Can you expand a bit?

Thx!
--
gk

Colin Vipurs

unread,
Nov 5, 2015, 5:48:57 AM11/5/15
to growing-object-o...@googlegroups.com

2) Yes, mostly  everybody is mostly procedural, I live through what you mean daily. :-( Half the time it is due to being lame. The other quarter of the time it is due to having seen some badness of OO.

This, and other messages here are suggesting to me that procedural is 'wrong' and should be avoided at all costs - and I disagree.   Procedural/OO/FP, much like London/Detroit school should all be about context and applying what you think is right at the time.   

The last time I looked at the Hibernate source code, albeit quite a lot of years ago, was a system that took OO to the extreme and it made it very difficult to follow any flow through the code.

The style I've been employed for a while now is to use all 3, which to me comes down to procedural at the top level which is the story flow, implemented by objects to get the actual work done and using functional for iteration/internals.

Luiz Augusto Moreira Costa

unread,
Nov 5, 2015, 8:22:25 AM11/5/15
to growing-object-o...@googlegroups.com
Hi Colin, 

Can you expand the ideal of "...procedural at the top level..."? Do you mean to abstract your flow in objects like services or use cases? 
I've been using the Use Cases objects for a long time and, for me, it's very simple to understand the application logic with them.

Can you share some code with us?

thank you.



--

Steve Freeman

unread,
Nov 5, 2015, 8:25:39 AM11/5/15
to growing-object-o...@googlegroups.com
Obviously procedural is part of the mix, there's a fundamental level where you can't do anything else.
S

Steve Freeman

unread,
Nov 5, 2015, 8:31:56 AM11/5/15
to growing-object-o...@googlegroups.com
perhaps encapsulated, stateless is a separate issue.

S

Mike Stockdale

unread,
Nov 5, 2015, 10:03:09 AM11/5/15
to growing-object-o...@googlegroups.com
Keith nails it!


On 2015-11-03 17:03, philip schwarz wrote:
Keith Braithwaite blogged: http://cumulative-hypotheses.org/2015/11/03/mocks/
But programmers tend to suffer from very bad target fixation when a tool becomes difficult to use and they put their head down and power through, when they should really stop and take a step back and think about what the hell they’re doing.

--
Cheers,
Mike Stockdale

fitSharp
Syterra Software Inc.

cdegroot

unread,
Nov 5, 2015, 12:25:31 PM11/5/15
to Growing Object-Oriented Software

On Wednesday, November 4, 2015 at 4:33:27 AM UTC-5, Matteo Vaccari wrote:
What can we do?
 
Apart from ignoring everything signed "dhh"? ;-)

Lead by example. I think that's pretty much the only way. Pretty much all code has a mix of functional/procedural/"OO"[1] and the trick is learning and teaching where to put the accents. Yesterday, I refactored some Scala code that was on the OO/functional side to procedural - after all, the code at hand was a straightforward process moving data from json messages to MySQL, no need to pull out the trickery machine. 

Lead by example. Every piece of code needs conscious style decisions. Learn how to make them and show others your reasoning. Hmm. I think I should say "learn by leading by example". My advise is always to attempt to write prose, not code. If your code tells the story of what your code is about, you've picked the right mode.

[1] OO. Worst term ever. I use it for lack of something better - with OO, people seem to mean programming by smearing your logic around in classes, but if you read up on how Smalltalk came to be, there was so much inspiration from e.g. Lisp that the distinction is largely blurry if you use the original OO language (you're using higher order functions in pretty much every method). So, frankly, I don't really know what OO means. And I'm afraid to stress the message sending and encapsulation aspects of it, because then the Akka people will run away with it.

Grzegorz Gałęzowski

unread,
Nov 5, 2015, 12:32:01 PM11/5/15
to Growing Object-Oriented Software
I didn't manage to watch the presentation, but I got through the blog post mentioned in the slides and my point of view on some of the points raised is different than author's. One of them is "Mocks and stubs require intimate knowledge of how code interacts with other modules"

In my design approach, this often isn't "intimate knowledge". I see a similar judgement made by Gerard Meszaros, who, in his book, put mocks and stubs in a chapter called "back door manipulation". This is a place where I fundamentally disagree. If an object A has the following constructor:

is instantiated like this:

new A(new B()); //assuming B instances are not values, but objects in GOOS terms

Then A's interactions with B are not its intimate knowledge. The reason is that (except some rare cases like final classes) when I instantiate A, I am allowed to pass a subtype of B (or if A takes an interface that B implements, another implementation of that interface). Whatever I decide to pass there (and the decision on what to pass is mine) I must pass something that is plug-compatible with A. To even stand a chance of creating something that is plug-compatible with A, I need to know the A's requirements for such compatibility. If A calls a method on B only once, then I might be less constrained with implementing this method than in a case where it is called many times.

As a naive example, let's say that A accepts an interface called Connection. This means that I can write my own connections and pass them to A when I instantiate it. Also, let's say that this Connection interface has three methods: open(), send(byte[] data) and close(). Now, if I want to implement my own connection, do I need to know that open() is called once, then send() can be called many times, but only after open() and, at last, that close() comes once at the very end? I argue that I need this information and that it is not intimate - while it is not part of A's public API, it remains part of its public contract. Without it, I don't have a fair chance of creating my own connection that works well with A.

Another point I would like to make is that changing from sending something to an interface to returning a value is not decoupling by definition. The most notable change is about who is coupled to what. Coupling through return values is as possible as through interfaces - part of what Tell Don't Ask says is about using return values so that there's no excessive coupling. The trick for me is creating a system where responsibilities are evenly distributed. I really like the ideas by Rebecca Wirfs-Brock of control styles: https://en.wikipedia.org/wiki/Responsibility-driven_design#Control_style . The trick for me is not to have a single class decoupled from interfaces to avoid mocks. The trick is to distribute the responsibilities so that no part is excessively coupled to others.

Tim Wood

unread,
Nov 7, 2015, 9:16:34 AM11/7/15
to growing-object-o...@googlegroups.com

On 5 Nov 2015 5:25 pm, "cdegroot" <cas...@gmail.com> wrote:
>
> [1] OO. Worst term ever. I use it for lack of something better - with OO, people seem to mean programming by smearing your logic around in classes, but if you read up on how Smalltalk came to be, there was so much inspiration from e.g. Lisp that the distinction is largely blurry if you use the original OO language (you're using higher order functions in pretty much every method). So, frankly, I don't really know what OO means. And I'm afraid to stress the message sending and encapsulation aspects of it, because then the Akka people will run away with it.


I am feeling reckless today, so I think I will stress the message sending and encapsulation aspects by quoting from the Smalltalk-80 book:

[Smalltalk  is  built  on  the  model  of  communicating  objects.  Large  applications  are  viewed  in  the  same  way  as  the  fundamental  units  from which  the  system  is  built.  The  interaction  between  the  most  primitive objects  is  viewed  in  the  same  way  as  the  highest-level  interaction  between  the  computer  and  the  user.  Objects  support  modularity--the functioning  of  any  object  does  not  depend  on  the  internal  details  of  other  objects.  The  complexity  of  the  system  is  reduced  by  this  minimization of interdependencies  of  system  components. ]

[The  message  does  not  specify  how  the  [operation]  will  be  performed. The  receiver  determines  how  to  accomplish  the  [operation].  Computing  is viewed  as  an  intrinsic  capability  of  objects  that  can  be  uniformly  invoked  by  sending  messages. The  set  of  messages  to  which  an  object  can  respond  is  called  its  interface  with  the  rest  of  the  system.  The  only  way  to  interact  with  an  object is  through  its  interface.  A  crucial  property  of  an  object  is  that  its  private  memory  can  be  manipulated  only  by  its  own  operations.  A  crucial property  of  messages  is  that  they  are  the  only  way  to  invoke  an  object's operations.  These  properties  insure  that  the  implementation  of  one  object  cannot  depend  on  the  internal  details  of  other  objects,  only  on  the messages  to  which  they  respond.

Messages  insure  the  modularity  of  the  system  because  they  specify the  type  of  operation  desired,  but  not  how  that  operation  should  be  accomplished.  For  example,  there  are  several  representations  of  numerical  values  in  the  Smalltalk-80  system.  Fractions,  small  integers,  large integers,  and  floating  point  numbers  are  represented  in  different  ways. They  all  understand  the  same  message  requesting  the  computation  of their  sum  with  another  number,  but  each  representation  implies  a  different  way  to  compute  that  sum.  To  interact  with  a  number  or  any  object,  one  need  only  know  what  messages  it  responds  to,  not  how  it  is represented.]

[An  important  part  of  designing  Smalltalk-80  programs  is  determining  which  kinds  of  objects  should  be  described  and  which  message names  provide  a  useful  vocabulary  of  interaction  among  these  objects. A  language  is  designed  whenever  the  programmer  specifies  the  messages  that  can  be  sent  to  an  object.  Appropriate  choice  of  objects  depends,  of  course,  on  the  purposes  to  which  the  object  will  be  put  and  the granularity  of  information  to  be  manipulated.]

[In  designing  a  Smalltalk-80  application,  then,  choice  of  objects  is  the first  key  step.  There  really  is  nothing  definitive  to  say  about  the  "right way"  to  choose  objects.  As  in  any  design  process,  this  is  an  acquired skill.  Different  choices  provide  different  bases  for  extending  an  application  or  for  using  the  objects  for  other  purposes.  The  skilled  Smalltalk-80 programmer  is  mindful  that  the  objects  created  for  an  application might  prove  more  useful  for  other  applications  if  a  semantically  complete  set  of  functions  for  an  object  is  specified.]

Steve Freeman

unread,
Nov 7, 2015, 9:39:28 AM11/7/15
to growing-object-o...@googlegroups.com
This is exactly why RonJ's post shows that he has no idea what we're talking about. The whole point of mocks is to test the interaction traffic, rather than by sucking state out of an object.

S

Raoul Duke

unread,
Nov 7, 2015, 9:46:05 PM11/7/15
to growing-object-o...@googlegroups.com
> This is exactly why RonJ's post shows that he has no idea what we're talking about. The whole point of mocks is to test the interaction traffic, rather than by sucking state out of an object.


if all you have are Beans, then everything looks like a foot you want to shoot.

Matt Wynne

unread,
Nov 9, 2015, 3:46:51 AM11/9/15
to growing-object-o...@googlegroups.com
Steve are you going to blog about this? I know you’re bored of it but it would be great to have your position stated clearly somewhere we can all refer to.
cheers,
Matt

---
ma...@mattwynne.net

Steve Freeman

unread,
Nov 9, 2015, 4:04:21 AM11/9/15
to growing-object-o...@googlegroups.com
I believe we wrote an entire book about this which neither Ron nor any of the these other people appear to have read. Also, Keith has written a fine response.

S

Luca Minudel

unread,
Nov 10, 2015, 4:43:06 AM11/10/15
to Growing Object-Oriented Software
> I think the ability to flow between object and functional styles, where appropriate, is very powerful.

The ability to see a continuum between available techniques (same for practices, tools, frameworks, etc) imh is a good indicator that someone has reached a level of mastery on those techniques.
When someone  look at two techniques as mutually excursive alternatives, sometime it's because:
- lack of understanding of the techniques, or
- will to differentiate, for social or economical convenience (i.e. influence, power, money)

Luca
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+unsubscribe@googlegroups.com.

Luca Minudel

unread,
Nov 10, 2015, 4:50:51 AM11/10/15
to Growing Object-Oriented Software
> it would be great to have your position stated clearly somewhere we can all refer to.

Matt, this would help to win a discussion based on authority (given that the other person recognize the authority you are referring to).
This is in the field of rhetoric, politic or cult.

As engineer of a technical and scientific discipline you should be able to show by facts in specific circumstances that your technical decision, inspired by a technique, is fit for purpose.

Luca
>> To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+unsubscribe@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages