Unit Test with Mockito – Easy Explained

If you are new with Mockito. This page is for you.
If you are confused how to write a unit test. This page is for you.
If you already have tried to read the default document of Mokito (from this link) and you are more confused, this page may help you. I got confused too when I have read that document.

Full Code 

mockito_example1.zip

What you need to run this:

  • Maven 3
  • Java 8

Easy Explanation:

Assume that you are creating a class named TransferMoneyService.  This class has its code like this.

This class is for transferring money. When it does the transfer, it does two things:

First, withdraw the money from the ‘fromAccount’ by calling this method:

Then, deposit the money to the ‘toAccount’ by calling this method:

Your problem is that you want to create a unit test for this TransferMoneyService class. Where should you start?

First, define what should be the target class that you want to test: In this case, it is TransferMoneyService.
Next, define what logic you want to verify or what you expect this class should do. Let say, you think that this class should do:

– call WithdrawMoneyService.withdraw()  to withdraw the correct amount of money from the correct account (fromAccount, not toAccount)

– call DepositMoneyService.deposit() to deposit the the correct amount of money to the correct account  (toAccount, not fromAccount)

– Important: your boss told you to make sure that it must be withdraw before deposit (To make sure that your bank will not lose anything)

Second, your next problem is that  WithdrawMoneyService.withdraw() and DepositMoneyService.deposit() call the database.  You saw someone wrote on internet that a good unit test should not call the database directly. You quite do not understand why, but since it is from internet, so you believe it.

To be more serious, when writing a unit test, you should think like this:

 “My target class is TransferMoneyService. I want to test  only TransferMoneyService, if TransferMoneyService calls other classes, I will only check that it calls other classes correctly. I will assume that the other classes will work correctly but I will not check that in my tests”

Let explain another way.
Now, you have classes and their relation like this picture:

You should NOT write a test that covers multiple class like  the green box in this picture:

You should have each test(s) for each class, like the green boxes in this picture:

The target class that we want to write a test for now is TransferMoneyService. We assume that someone who wrote WithdrawMoneyService and DepositMoneyService have done their job by writing proper unit tests for both of those classes.

So, let start writing the test.

You need Junit  and Mockito 

Since we do not care about the actual executions of WithdrawMoneyServer nor DepositeMoneyService, then we mock them up.

These mock() method creates a “fake” object (normally it is called “stub”). If you call method on a fake object, for example mockDepositeService.deposit(), it will do nothing.

Use them when create an TransferMoneyService object:

Call the transfer() method:

Verify that it has really called mockWithdrawMoneyService.withdraw(“accountA”,100) only 1 time:

This syntax may not be intuitive. It means “verify on this object that the withdraw() method has been called with parameters as accountA and 100 (double)”

Verify that it has also called mockWithdrawMoneyService.deposit(“accountB”,100) only 1 time:

Verify that it has called withdraw() before deposit()

Same, it is quite not intuitive. It means “collect the order information in inOrder,  then verify the order that withdraw() has been called before deposit()”

The full code of test looks like this:

If you run the test , it will pass. How to run the test?

– via IDE: try to right click and select run  “test_transfer”

– via command line with maven: type “mvn test”, it should tell you that it is success.

Now, you should try to make it fail. Why should you do that? to make sure that it is really test something. You can try these:

– In TransferMoneyService.transfer(), try to change order by calling deposit() before withdraw(). And run the test again.

– In TransferMoneyService.transfer(), try to type change deposit(toAccount,amount) to deposit(fromAccount,amount). And run the test again.

Ok, now you should get some ideas about how to write the test. I hope that after read this post, now the default document of Mokito (from this link) should make more sense for you.

However, most of us are working with legacy code,  the DepositMoneyService and WithdrawMoneyService are not created outside but inside like this code:

Then you need to use “spy”, which is explained in here How to use spy in Mockito.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">