Writing Maintainable Tests: Overspecification in Unit tests
Tags: testing, tdd, unittestting
Published: 2021-12-02 08:19:21

Hello Everybody :smile;
Happy To Write Today
Today we will finish the part about **Writing Maintainable Tests** with the concept of **Overspecification in unit test**. So let's dive in.


## What is an Overspecified Test ?

Read this from Roy
>An overspecified test is one that contains assumptions about how a specific unit under test (production code) should implement its internal behavior, instead of only checking that the end behavior is correct.

Simply said we are writing an overspecified test when we focus on internal things rather than the end behaviour of the unit  we are testing .



## The Patterns of an Overspecified Test

1. A test asserts purely internal state in an object under test.

2. A test uses stubs also as mocks.

3. A test assumes specific order or exact string matches when it isn’t required.

we will look at each specifically


![overspecified test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/khtr7evmzbhzpqcadxpj.gif)


## 1. Specifying Purely Internal Behaviour 

Internal State can change more frequently than the end behaviour , if we are writing a unit test about internal state we are writing a **fragile Unit test**.
The code below shows it : 

```
[Test]
public void Initialize_WhenCalled_SetsDefaultDelimiterIsTabDelimiter()
{
   LogAnalyzer log = new LogAnalyzer();
  Assert.AreEqual(null,log.GetInternalDefaultDelimiter());
  log.Initialize();
  Assert.AreEqual('\t', log.GetInternalDefaultDelimiter());
}

``` 
:flushed: Why testing the **Initialize method** , is it worth it for the end behaviour ? Sometimes no :unamused: .

I can say nothing better than what Roy Says :

>This test is overspecified because it only tests the internal state of the LogAnalyzer object. Because this state is internal, it could change later on. Unit tests should be testing the public contract and public functionality of an object. In this example, the tested code isn’t part of any public contract or interface




## 2. Assuming and Order or Exact Match when it is not needed
I admit it , sometimes i have done it , assert against a specific string message and when the requirements change so the message changes also and my unit test breaks. So the Simple question is Can I use **string.Contains()** rather than **string.Equals() ?**

> The same goes for collections and lists. It’s much better to make sure a collection contains an expected item than to assert that the item is in a specific place in a collection (unless that’s exactly what’s expected).By making these kinds of small adjustments, you can guarantee that as long as the string or collection contains what’s expected, the test will pass. Even if the implementation or order of the string or collection changes, you won’t have to go back and change every little character you add to a string.

Simple , Clear , Understandable. :stuck_out_tongue_winking_eye:



## 3. Using Stubs Also As Mocks

The main words here are 

>As long as the end value still holds, your test shouldn’t care that something internal was called or not called at all.

The End Behaviour, The End Behviour , The End Behaviour , the internal way to achieve the end behaviour is not important it can change , but what the end user wants is the end behaviour.





Thanks For Reading :blush:. If you have any questions feel free to write me.
By the Grace of JESUS :heart: I will start another series of post about **Readable Unit Tests**.