0

I am currently learning TDD and i was wondering about the real meaning of Uncle Bob's sentence about refacto step in connection with TDD. The subject talks about Test Contra-variance in TDD and it comes from his Clean Coder Blog.

Context : Suppose I begin writing a new class. Call it X. I first write a new test class named XTest. As I add more and more unit tests to XTest I add more and more code to X and i refactor that code by extracting private methods from the original functions that are called by XTest.

Then i have to refactor the tests too. (this is where i have a misunderstanding)

About this step, Uncle Bob Said :

I look at the coupling between XTest and X and I work to minimize it. I might do this by adding constructor arguments to X or raising the abstraction level of the arguments I pass into X. I may even impose a polymorphic interface between XTest and X.

My questions are : How to identify coupling ? What does he mean by "adding constructor arguments to X or raising the abstraction level of the arguments I pass into X." and "polymorphic interface between XTest and X."

A sample code would be very welcome !! :):)

Link to the blog article in question : https://blog.cleancoder.com/uncle-bob/2017/10/03/TestContravariance.html

Thank in advance.

MigMax
  • 80
  • 4

1 Answers1

3

How to identify coupling ?

Start with this heuristic: if a change here requires that you also make a change there, then you have coupling between the two.

Coupling, of itself, isn't necessarily bad: I've got a lot of ten year old code that is tightly coupled to the java collections library, and that code is fine. I don't get burned, because the thing that I am coupled to is stable.

Being tightly coupled to things that are unstable is a miserable existence.

When the unstable thing is our own code, we can sometimes remedy the problem by changing our design, so that the point of coupling becomes stable, rather than unstable.

Broadly, "what he means by..." is creating a stable contract between the test, and the test subject. The test subject must satisfy the contract, but that contract describes the behaviors (what you can see from outside the black box) not the implementation.

If instead of starting from "I need FooClass, and therefore FooTest", you begin with "I need FooBehavior and therefore FooTest"; then you are much closer to the target of having a mistake detector that you can use unchanged while you iterate on the implementation of that behavior.

On the other hand, when the behavior itself is unstable, this isn't going to help. In that case, you are going to need other techniques. See Rich Hichey's talk Spec-ulation, where he talks about the power of accretion.

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91