How Tests Find Bad Code

You probably already had to write tests for someone else his code. Then you know how troublesome it can be, especially to know what you actually should verify on. But another problem that can arise is that you realise the code is just not written very well. While the main reason for tests is to verify the correctness of code, tests can also be used to test the behaviour and cleanliness of code. This is a hidden benifit of tests which is often neglected by many people.

The hidden benefit does not come free however, but neither does the actual usage of it. Just as you can write tests that do not verify the code at all, you can have tests that do not verify the behaviour or cleanliness of the code. Moreover, if you do not take caution in how you write your tests you may even make your code less clean or deteriorate it for the sake of test-ability. I have often seen methods being written just to steer the internals of the object so it can be tested.

Writing tests are a good way to test your API as tests have to operate with the exact same methods as other objects. This is a good way to verify that the API is easy to use and makes sense, moreover this means that the API is automatically documented with the expected behaviour for the different cases. Again, it is important that you do not alter your API just for the sake of test-ability. Creating getters, setters or other special methods means that these methods are also available for the real code, while they should not be used!

The need for these special methods can either be driven by laziness as they offer the easiest way to quickly verify a state of an object, or by bad design. If you need to do all this effort to test your code, can you imagine the work the actual code needs to do to get the object to do what it should be doing? It is even worse of these methods are created because they are used in the production code as this means that the API is not very clear and often causes a higher level of coupling that required.

Getters are a good example of this, while they often make it easier to verify the state of an object, creating them for the sake of tests is bad as it exposes too much details of the object. However, it is much worse if the getters are actual part of the API. Setters are often used because you need to change an object reference. Again there should be no reason for this method, as the reference should be created just like the production code does. If this however is how the production code works, then it is essential that this is tested very well, because having such a method means that this object reference can be altered at any given moment which is often not desired nor supported.

If you create real unit tests and mock all other components then you can easily verify calls to other components. Moreover the amount of mocks and which calls need to be stubbed gives you an indication of how this object is integrated with the others. If you have to create a lot of mocks with many stubbed methods your code is closely-coupled which will give you problems in the future. There can be many reasons for this, but it is a clear sign to investigate the code and should convince you to improve, and clean it. This will make testing the code easier, but more important it will also improve the maintainability and readability of the code.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.