In this post I would like to explain what is a unit test. In the first moment it seems to be redundant and useless. For now there are a lot articles, posts, books in an internet about testing, TDD etc. Everyone knows what “UT” is. Well, maybe not everyone. And sometimes it happens that developers in one team have different testing approaches and there are significant discrepancies between them. Unfortunately, often after looking into the code, we find out that no one knows or did not want to know where the border between the unit test and the module test is. Therefore, I will give my definition and then I will use it to answer most popular questions asked during unit test development.
My definition of unit test
The test is unitary (and only if) when the implementation used from the production code comes exclusively from the implementation of the tested unit. The purpose of the unit test is to check the Tested Unit interface behavior correctness.
Of course, this is my definition, written from my subjective point of view. It is important that I assume in it that we know what the test itself is. To clarify this definition, let’s ask ourselves a few questions and try to answer them.
Member of tested unit is an object – should I stub or mock it?
No. This object is a class’ member, created by tested unit, it is invisible from an interface perspective, so we include that object’s source files to unit test build system.
Tested Unit’s method returns object of type X. Should I stub or mock it?
It depends on what created returned object. If it is created by the Tested Unit (or Tested Unit member) answer is: no. If returned object is only processed after injection to Tested Unit, then we should mock it and check only the call on that mock.
I pass to Tested Unit methodless object, how to mock or stub that?
We do mock or stub methodless classed or structures. Of course if the class has simple elements like a constructor, which only assign initial members’ values let’s treat it like simple object.
An Object is not injected to Tested Unit, but I need change it outside or check calls on it.
Should you mock it or not? Unit Test does not know anything about internal implementation. If we don’t inject it, how do we know that it is there? It smells like singleton or using global variables. You have to change your architecture and please don’t use antipatterns anymore. I encourage you to enter “singleton stack overflow” in the search engine. Search result titles themselves should give food for thought. We consider creating separate post about it. No singleton or global variables? So maybe you try to use white box approach? If yes, wait for our post about “Black box testing vs white box testing” 🙂
It is not possible…
I think you could find cases where it would be allowed to do otherwise than I wrote above. However, in most cases, where the code forces you to do differently than I wrote, it means one thing: you work with poorly designed code. What to do with this? Simple answer: refactoring. Don’t be lazy. The faster errors are fixed, the less resonance they have. The better the code is designed, the more pleasant it is to write it and the less the likelihood of errors in the application. Of course, most would answer me: we don’t have time to correct the code, the manager wants it for now. Another post can be dedicated to discussing this topic. And it’s long. This one is supposed to be short. Let’s leave this topic open.