Working Effectively with Legacy Code : Sensing And Separation
Tags: testing, legacycode, tdd
Published: 2021-11-27 08:26:51

Hello :smile:
Today it is a small article again about our daily routine when we are against a legacy code and how to deal with it and make it clean. Today i will try to explain the concepts of _sensing_ and _separation_ .


## The Problem

The **Core Problem** is that , yes legacy code is code without tests i agree , but how can i introduce tests in a project where a class depends on another class that depends on another class . I do not know how to deal with that loop.
This is where we all are :worried:


Remember that to give passion to that legacy code we have to use a tool named **unit test** , in other words a **small world** where our class is tested or can truly explain herself. Now your question remains **how create this small world only for my class when she has a lot of dependencies** .


## The Solution
To deal with all these dependencies M. Feathers gives us two words that are really important i think **sensing** and **separation**. 


## Sensing
When we can not sense ? This is when our class has some method , and we do not know exactly the work behind the hood of that method call.
In our _small world_ we are going to sense that call to see the effects behind the hoods. 


## Separation
When can not we separate ? This happens when for example to execute a method call we need all the system to be running.
In our _small world_ we are going to **break the dependencies** for this method call on the system .


So you might guess , How to Break my class or my method dependencies ? :weary:



![legacy code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9hw7296z6equkatx6buz.gif)


## Faking Collaborators
This is i think the superpower we have as a developer when we create this _small world_ for our class , to break dependencies we are going to **create fake objects** , 

Read what M. Feathers says :
>If we want to execute a piece of code by itself and see what it does, often we have to break dependencies on other code. But it’s hardly ever that simple. Often that other code is the only place we can easily sense the effects of our actions. If we can put some other code in its place and test through it, we can write our tests. In object orientation, these other pieces of code are often called **fake objects**

:astonished: Now we know how to create this SMALL WORLD. But wait :sweat:,

## What is a Fake Objects ?

I do not know if you have great example in daily life , this sentence sounds good enough : **A fake object is an object that impersonates some collaborator of your class when it is being tested**



## Practical demonstration
I will use Example from the book, they are highly well presented so that everybody can understand **Fake Objects**

Saying that we have a class that depends on X in the real system , like below we see that the **Sale Class Uses the ArtR56Display Class**


![legacy code, fake objects](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xi0rn3sc35gnfsopj5wn.png)



You are saying that to work **The Sale Class needs a Display element to work** ? Yes
So what is a Display element , it is just a Interface like below 
 
```
public interface Display
{
   void showLine(String line);
}
```

If i understand to work the **Sale Class needs every class that Implements the Display Interface** isn't it ? You are absolutely Right

Now where is the Fake Object, Where is the small world ? Be Patient it is there look below :wink: 


![legacy code , fake two](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t6ra0n8xuptv2m56kbdt.png)


You see Now ? When we have give existence to our Fake Object now we can go with our small country/world where our star( The Sale Class) can talk about herself without worrying about others universe .


```
import junit.framework.*;

public class SaleTest extends TestCase
 {
    public void testDisplayAnItem() {
    FakeDisplay display = new FakeDisplay();
    Sale sale = new Sale(display);
   
    sale.scan("1");
    assertEquals("Milk $3.99", display.getLastLine());
    }
}
```
Do you see rather to make all the system runs , **we have build our small world with our Sale Class Communicating with our Fake Object** :sunglasses:
**Now we can sense our method calls and we have separate our method calls from all the system.**

You have successfully create a small world for the first class in your legacy Code base. :fire:


## What I Think ?
At The beginning i admit i had not understand it , you know what helped me , this beautiful article [Mocks are not stubs](https://martinfowler.com/articles/mocksArentStubs.html) from Martin Fowler. When you grasp the light , you start seeing unit testing another way :heart: 







Thanks for Reading :wave: , By the Grace of JESUS :sparkling_heart: i will continue giving you the powerful advices in This Book [Working Effectively With Legacy Code](https://www.amazon.fr/FEATHERS-WORK-EFFECT-LEG-CODE/dp/0131177052 )