About Ram Mokkapaty

Ram holds a master's degree in Machine Design from IT B.H.U. His expertise lies in test driven development and re-factoring. He is passionate about open source technologies and actively blogs on various java and open-source technologies like spring. He works as a principal Engineer in the logistics domain.

Mockito Hello World Example

You are here, it means either you are interested in the mock objects or you are already aware of Mockito, and you want to see a working example of it. Well…let me first introduce you to Mockito which is an open source mock unit testing framework for Java. In this article, I am going to show you a Hello World example of Mockito. You will learn how to use it for mock object creation, stubbing and verification. I’ll also explain in detail how mock objects work, how they encourage testing based on behavior verification.

Note that Foo is just an interface. Let’s imagine that the implementation would be provided by some other team which is either still working on it or is not yet done with the implementation. Now assuming that a portion of your component is dependent on Foo‘s API, the idea of you waiting for the delivery of Foo is not so encouraging. This is where we will have to switch hats and apply a mockist approach to our problem.

2.1. Building Mock Object

Let’s write our first test that will allow us to peep into Mockito’s world.

Our first scenario would be to call foo.greet() and make it return “Hello World”. This will introduce us to concepts like mocking and training the mock object.

Our test consists of:

Creating a mock Foo object

and then train it to return us “Hello World” when Foo.greet() is called. This will set up the expectations that we have from the mock object.

2.2. Mockito APIs Used

Let’s now review the Mockito APIs that we have called.

We have used Mockito.mock(Foo.class) to create the mock object. Since will be calling Mockito APIs quite often, we can improve the clarity of API call by statically importing the package org.mockito.Mockito.*. We don’t have to make the explicit static calls any more. If you notice in our above test, to create the mock object, I have simply called mock(Foo.class).

The next thing we do is to setup our expectations. Our expectation is, when foo.greet() is called then return ‘Hello World’. The API construction is designed to be more readable and English like. To achieve it, we call:

when(foo.greet()).thenReturn(HELLO_WORLD)

The API follows builder pattern where each method returns us an Object of type OngoingStubbing so that we can stub further on the returned object thus allowing us to build the expectations fluently.

2.3. System Under Test

Ok, this works but that’s not our goal. Foo is only a collaborator and not the system under test, also fondly called, SUT. Let’s bring our SUT Bar into the field.

Bar has a method called greet(Foo) which takes in a Foo object, makes a call to foo.greet() and returns us Foo‘s greeting.

We will now add our new test barGreets() which just makes sure that Foo returns us the proper response. Since even our second test makes use of the mock object, we have moved the setting up of mock object to our new configuration method setupMock(), which is a @BeforeMethod that gets called right before the invocation of each test method.

Ok, that looks good. We have a SUT and a collaborator. We are able to test SUT even though the actual collaborator implementation is not yet available. Thanks to the Mock object!.

If you notice, Bar is way too simplistic. Let’s spice it up and add a few conditions.

3. Behavior Verification

We will now add a new method to Bar called question(Foo foo, String question) which takes in a question, sends it to Foo and then returns us Foo‘s answer. As promised, we will spice it up a bit with a few conditions:

First, we need to make sure Foo is available. We will know it is available when foo.greet() returns us “Hello World”.

If Foo is unavailable, Bar will not question Foo any more and instead will throw FooNotAvailable exception.

Foo will answer only certain questions..

Any other question sent, Bar will simply filter it out, without requesting Foo for an answer and instead will return “Invalid Question”.

Foo is down so will not respond
Bar sends a question to Foo but since Foo is not avilable will throw FooNotAvailable
Is Foo available?
No
PASSED: fooNotAvailable
Bar asks Foo 'Any new topics?', it should get a response
Is Foo available?
Yes
Verify that Foo has been asked the question
PASSED: barQuestionsFoo
Is Foo available?
Yes
Verify that question was never requested as Foo is unavailable
PASSED: filterInvalidQuestions

barQuestionsFoo sends a valid question to the Bar and then verifies whether it has been delegated to Foo.question for an answer.

filterInvalidQuestions sends an invalid question to the Bar and then verifies that Foo.question has not been called.

4. Mock Object throwing Exceptions

Till now, it was Bar, deciding whether a question is valid. Let’s push this responsibility to Foo. This makes sense as it is Foo which has to decide whether to answer or not. Since Foo now knows which one is valid and which is not, in case of an invalid question, it will reject the question and throw an InvalidQuestion exception. With this change, our Foo interface looks like below.

Our new scenario is, when foo.questionStrictly() is passed an invalid question, Foo should throw InvalidQuestion. The exception expected is setup using thenThrow() API which accepts the exception to be thrown. After the setup, bar.questionStrictly() is called with the invalid question. Our expectedExceptions test attribute makes sure that the exception is thrown.

5. More Behavior Verification using ArgumentMatcher and Answer Callback

We will further modify our Bar class so that now it can respond to the answers received from Foo. Based on the answer received, it will make further calls to Foo.Bar will ask Foo, whether there are any new topics of discussion. For example, a tutorial topic. Foo may either answer in affirmative or negative. If they are no new topics, Bar will call foo.bye() to indicate the end of discussion.
If there are new topics, Bar will further ask Foo the current day’s topic and its price. Once it receives the price, it will call foo.bye() to end the session.

In our previous test case throwExceptionIfInvalidQuestion, we had explicitly checked for “Invalid Question” but note that there can be more questions which fall into the invalid zone. Also, since Bar now responds to answers, we need to setup our mock object to map the questions and answers.

Is Foo available?
Yes
Invalid question
PASSED: throwExceptionIfAnyInvalidQuestion
Is Foo available?
Yes
Are there any new topics?
Yes
What is todays topic?
Topic name is Mockito
What is the price?
Price is 20
Let's quit now
Answer is: Topic is Mockito, price is 20
PASSED: getTodaysTopicPrice
Is Foo available?
Yes
Are there any new topics?
No
Let's quit now
Answer is: No
PASSED: noNewTopic

Mock objects return expected values. But when it needs to return different values for different arguments, Mockito’s argument matcher comes into play. In our case, the system has to behave in one way if the questions asked are valid ones and in a different way if they are ‘invalid’ which the collaborator doesn’t know how to respond.

Let’s go through our new test cases:

throwExceptionIfAnyInvalidQuestion – instead of testing the code against one invalid value, it now tests on a sub-set of values using the ArgumentMatcher

We pass in a org.mockito.ArgumentMatcher object to argThat(), so that the argument passed in to foo.questionStrictly() can be tested against the matcher to know whether it is one of the arguments expected by the mock object. If yes, then the next stub action will follow, in our case, the method will throw an InvalidQuestion exception, if the argument value is not a valid question.

getTodaysTopicPrice – here our Bar asks Foo whether there are new tutorials. The question asked is one of the valid ones so Foo responds with the current topic. Bar then asks for the price of the latest tutorial. Finally, Bar requests Foo to end the session calling foo.bye(). We setup our expectations on the mock object using the below statements.

After this, we do the verification to make sure that questionStrictly has interacted with Foo the way we wanted.
Once Foo responds that there are new topics, Bar asks Foo further details about the topic and then finally exits.
We do the verification of the calls made to Foo below:

Newsletter

Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

Email address:

Receive Java & Developer job alerts in your Area

Leave this field empty if you're human:

Join Us

With 1,240,600 monthly unique visitors and over 500 authors we are placed among the top Java related sites around. Constantly being on the lookout for partners; we encourage you to join us. So If you have a blog with unique and interesting content then you should check out our JCG partners program. You can also be a guest writer for Java Code Geeks and hone your writing skills!

Disclaimer

All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners. Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.