Introduction to Mockito
After we have finished this lesson, we
- Can get the required dependencies with Maven and Gradle.
- Know what Mockito is.
- Understand what we have to take into account when we create test doubles with Mockito.
Getting the Required Dependencies
Before we can create test doubles with Mockito, we have to get the required dependencies. We can do this by declaring the mockito-core dependency (version 1.10.19) in our build script.
If we are using Maven, we can declare this dependency by adding the following snippet into our pom.xml file:
1<dependency>
2 <groupId>org.mockito</groupId>
3 <artifactId>mockito-core</artifactId>
4 <version>1.10.19</version>
5 <scope>test</scope>
6</dependency>
If we are using Gradle, we can declare this dependency by adding the following snippet into our build.gradle file:
1dependencies {
2 testCompile(
3 'org.mockito:mockito-core:1.10.19'
4 )
5}
After we have added the mockito-core dependency into our classpath, we can create test doubles with Mockito. However, the problem is that we don’t know what Mockito is and how we can use it.
Mockito 101
Mockito is a popular mocking framework that can be used for creating different test doubles such as stubs, mocks, spies, and dummies.
Let’s move on and take a look at the Mockito APIs.
Introduction to Mockito APIs
Mockito has two different APIs that are described in the following:
- The
org.mockito.Mockitoclass provides the original Mockito API. This API uses the When-Then syntax. - The
org.mockito.BDDMockitoclass provides the new API that supports BDD style testing (aka Given-When-Then syntax). It was created because the original API is a bit confusing if you are writing BDD style tests. The problem is that the word when doesn’t integrate nicely with the//given //when //thencomments that are often used in BDD style tests.
The video lessons of this course use BDDMockito, but the text versions of these lessons have examples that use both APIs.
Additional Reading:
Let’s move on and find out what we have to take into account when we create test doubles with Mockito.
Creating Test Doubles with Mockito
Before we can create test doubles with Mockito, we should know these three “rules”:
First, the test doubles that are created with Mockito are not stateless. This means that if we are writing unit tests, we must create a new test double before a test method is invoked. This ensures that our test methods do not fail because they use a test double that has invalid configuration.
Second, we should create our test doubles by using one of these two options:
- If we want to create a stub, a mock, or a dummy, we should use the
mock()method of theMockitoclass. - If we want to create a spy, we have to invoke the
spy()method of theMockitoclass.
Additional Reading:
I argue that we should create our test doubles in a setup method that is annotated with the @Before annotation. I think that this approach has two benefits:
- We notice if the system under test has too many dependencies. The thing is that creating test doubles manually is a bit annoying, and that is why it helps us to notice if the system the under test has too many responsibilities. If it gets too annoying, we should refactor our code.
- It doesn’t force us to use a custom test runner. Mockito provides a custom test runner that can create our test doubles for us as long as we have annotated our test doubles with the correct annotations. The problem is that this approach encourages us to ignore the problems caused by too many dependencies and it forces us to use a custom test runner. That is why I won’t use this approach in this course.
By the way, I know that we don’t have to use a custom test runner if we want to initialize our test doubles which are annotated with Mockito annotations. However, I don’t recommend using this approach because it hides the fact that the system test test has too many dependencies. If you want to use this approach, you should take a look at the Mockito reference manual .
Also, if we want to create a dummy, we might want to do it in the test method. I think that this is a good option if the created dummy is used by only one test method or if creating it in the test method makes our test easier to read.
Third, we should not add the type of the test double to the name of the field or variable that contains a reference to the created test double. I think that this is a bad idea because the type of the test double doesn’t really describe the purpose of our test double. We should remember that a test double is not just a stub, a mock, a spy, or a dummy. It is an object that is required by the system under test and its name should reflect this.
Here are some examples that demonstrate my point:
- If we create a
TaskFinderstub that returns the same object every time when itsfind()method is invoked, we should use the name:taskFinderorfinderbecause the purpose of theTaskFinderis find tasks by using a specific search criteria. - If we create
TaskRepositorymock that provides CRUD operations forTaskobjects, we should use the name:taskRepositoryorrepositorybecause this object acts as a link between our application and the used database. - If we create a dummy that is not relevant for our test case, we should use the name:
notImportantornotUsedbecause this object is irrelevant for our test case.
We are ready to put our new skills into practice. Let’s summarize what we learned from this lesson.
Summary
This lesson has taught us five things:
- Before we can create test doubles with Mockito, we have to declare the
mockito-coredependency in our build script. - We can create stubs, mocks, spies, and dummies by using Mockito.
- We should create our test doubles before a test method is invoked.
- We should create our test doubles in a setup method that is annotated with the
@Beforeannotation. - We should not add the type of the test double to the name of the field or variable that contains a reference to the created test double.