Basics of Unit Testing
A lot of times, unit testing is discarded because of lack of time, lack of knowledge, or just because the client didn’t ask for it. This article has the goal to show you the importance of unit testing and share some best practices of making it better and easier to start.
What is unit testing?
As the name says, it is testing every area/function (or unit) of your code.
What is the goal of unit testing?
Make sure that those areas/functions (or units) work as expected.
What should I test or what should not I test?
For many people the more common question is which areas/functions to test. In my point of point it is better to define, WHAT I SHOULD NOT TEST:
- Other framework libraries (you should assume they work correctly, because they should have their own tests)
- The database (you should assume it works correctly when it is available)
- Trivial code (like getters and setters )
- Code that has non deterministic results (Think Thread order or random numbers)
WHAT SHOULD I TEST?
- Business logic
- Everything that contains conditions
What are the main advantages of unit testing?
Apart of guarantee that your code is working as expected you also have other advantages, like:
Safe refactoring and better code maintenance
Once you already tested the logic of your code, you can change/improve it, being always aware that the unit tests need to pass.
Most of the developers were a witness of situation like this:
Scenario : “Let’s make a small fix!!!”
Action: Developer changes a “simple” line of code.
Result: This quick fix solve the problem but broke other parts of the code.
- with unit tests: Unit tests failed -> the developer noticed that -> he refactors the code maintaining the proper logic.
- without unit tests: The developer noticed the problem in production (worst case scenario).

Fewer bugs
Once you are testing individual pieces of code (consequentiality smaller pieces of code), unit testing helps you to find earlier bugs in your code.
You will always think that your code is working properly, until you make unit tests
Good practices
Name convention
All the tests name should be consistent, therefore it’s a good practice define a name convention for your project. Usually, I’m comfortable to use this one:
test[feature being tested][behaviour expected]
testGetListOfCarsOnSuccessEmptyList
testGetListOfCarsOnSuccessFilledList
testGetListOfCarsOnError
You can see more name convention here.
Positive (and) negative tests
Apart of testing the behaviour expected, we should always be sure that we don’t receive the opposite behaviour.

For example, if we are testing a “OnSuccess” callback logic, we should be sure that “OnError” logic is never called. Something like this:
@Test
public void getCarsListOnSuccessEmptyList() throws Exception {
//given
//when
presenter.getCarsList(); //then
carsCaptor.getValue().onNext(new ArrayList<>()); //<POSITIVE TEST>
verify(mockView, times(1)).showCarsList(); //<NEGATIVE TEST>
verify(mockView, never()).showErrorMsg();
verifyNoMoreInteractions(mockView);
}
Template given-when-then
It’s a good habit to “split” a unit test in these 3 blocks (given-when-then)
//given = preparation
- test initialisation + stubs/mocks creation
//when = execution
- where the operation to be tested is performed
//then = assertion
- received result assertion + mocks verification

Given
a user previously received a gift (that can be open)
When
he opens the giftThen
he should see the opened gift screen
An alternative test division syntax (with very similar meaning) is AAA = arrange, act, assert.

If you using Java, let’s discover the powerful skills of Mockito. (In case of using Kotlin, have a look at Mockito + Kotlin)
Spy versus Mock
“The mock simply creates a bare-bones shell instance of the Class, entirely instrumented to track interactions with it.” — like a interface
Spy is more than a mock. It wraps an existing instance, where you can “call all the normal methods of the object while still tracking every interaction, just as you would with a mock.”
More info about Spy vs Mock.
InjectMocks
It allows you to create a class that depends of others, without calling the constructor. For example:
You want to test BasePresenter class, that depends of a UseCase.
//base code
public class BasePresenter {
private UseCase useCase;
public BasePresenter(UseCase useCase) {
this.useCase = useCase;
} public List<Thing> getThings(){
return useCase.getThings();
}
}
generic way
//unit test
public class BasePresenterTest { @Rule
public MockitoRule rule = MockitoJUnit.rule(); @Mock UseCase mockUseCase; BasePresenter presenter; @Before
public void setUp {
presenter = new BasePresenter(mockUseCase);
} @Test
public void testGetThings {
...
presenter.getThings();
...
}}
mockito with InjectMocks way:
//unit test
public class BasePresenterTest { @Rule
public MockitoRule rule = MockitoJUnit.rule(); @Mock UseCase mockUseCase; @InjectMocks BasePresenter presenter; @Test
public void testGetThings {
...
presenter.getThings();
...
}
}
When /ThenReturn
With these instructions you can control and determine whether to return the specified result
List<Thing> controlledList = new ArrayList();
controlledList.add(new Thing("testName1"));
controlledList.add(new Thing("testName2"));when(presenter.getThings()).thenReturn(controlledList);
//after this, your presenter.getThings will return you a list with 2 "Thing"s
More examples about it here.
Verify number of calls
You can verify how many times your methods are called, the number of interactions with your classes, like this:
// verify is show error msg was called once
verify(view, times(1)).showErrorMsg(any(ErrorMsg.class));// verify is show error was never called
verify(view, never()).showErrorMsg(any(ErrorMsg.class));//verify if view will not suffer more interactions after this point
verifyNoMoreInteractions(view);//verify no interactions with all useCase mock verifyZeroInteractions(useCase);//verify order of calls (verify if view.showLoading() is called first of presenter.manageError())InOrder inOrder = inOrder(view, presenter);
inOrder.verify(view).showLoading();
inOrder.verify(presenter).manageError();
Conclusion
“Tests are stories we tell the next generation of programmers on a project.” — Roy Osherove