Let's suppose that we have to write tests for presenter or viewmodel that supports two paths: anonymous and logged in user. We have use cases telling us if user is currently logged in, use case for fetching feed which we will present to the user and router for handling some of navigation events.
For logged in user, on start:
we have to fetch feed for that user
we have to subscribe to notifications
we have to set users avatar
on settings icon click, we have to open setting screen
But for anonymous user:
we fetch some generic feed "most popular"
we don't subscribe to notifications
we set default avatar
on settings icon click, we open login / registration screen
Presenter dependencies are described by the following interfaces:
We have several test cases that slightly differs for logged in and anonymous flows:
And presenter will look like this:
Eventually when we will start implementing tests in given-when-then manner they may look like this:
There is a way to refactor those tests without too much modification. We will use @Nested annotation and inner class.
So what we did here?
Selected two paths: logged in and anonymous
Created two inner classes with @Nested annotation in test class
Created stub for ResolveUserUseCase once per nested test
Refactored test names a little bit, so we wouldn't have given twice renderedin test result
If you want to make use of nested tests in your project, make sure that you are actually using Junit5 instead of Junit4.
Nesting test in Junit5 is interesting feature, it makes easier following Don't Repeat Yourself principle, since we have more convenient of for sharing test doubles between common test cases.
While we are refactoring tests to make use of nesting mechanism, we may come up with some refactoring ideas - maybe some parts of system under test that are now covered with @Nested mechanism deserves extraction to separate class?
It is also some way of introducing BDD style into test suite - in nested groups we can define tests for common behaviors in more readable way.
And last but not least - IDE support for nested tests really speaks to me. One thing is displaying test result, and the other - possibility of running only part of test class.