You are on page 1of 4

Abhi

Java, Linux, Development, Comics and Awesomeness

Java and Related Linux How Tos Blogging How Tos Comics by Abhi Aaaasome Posts NandOO Labs

Thursday, June 7, 2012 Tag Cloud

JMockit Tutorial:Learn it today with examples


Amazon Links

JMockit is one of the many mocking frameworks available for unit testing in Java. If you have to unit test you'll
Search This Blog
invariably end up mocking objects for third party classes and for stubbing.

Search
I assume you already know JUnit. We'll see step by step in very short tutorials that'll help you start using jmockit. I'll
be trying to keep each one as crisp as possible. If you want more details.You can ask them in comments section
below...

Categories
I am yet to understand some of the JMockit features completely, so please bear with me if I have not covered it in
entirety.
java
Linux
eclipse
comic
rage comic
blogger
blogging
jmockit
junit
Grub2
Ubuntu
command
global warming
mysql
vi
1. What is Mocking in unit Testing?
editor
DellDatasafe
EasyBCD
India
2. How does JMockit support mocking? database
meme
quotes
shell script
sql
3. How to add JMockit to an eclipse project? stumble upon
4. How to run a test case with JMockit?
5. How to mock default constructors(or constructors with no parameters) in JMockit?
6. How to mock constructors with parameters (or those that take arguments) ? Popular Posts
7. How to mock static initialization blocks in JMockit?
JMockit Tutorial:Learn it today
8. How to mock public methods in JMockit with examples
9. How to mock  private methods in JMockit?
10. How to mock static methods in JMockit? Java : How To Read a
Complete Text File into a String
11. How to invoke or test private methods in JMockit?
12. How to throw exceptions in an Expectations block? How to split on "\" or backslash
13. Some more JMockit utilities before signing off. in Java

JMockit Tutorial: How does


JMockit support mocking?

How to mock constructors in JMockit? What is Mocking in unit


Testing?
Consider the code below:

Blog Archive
/************************* Person.java ****************/

public class Person {


August (1)

private String name;

November (1)

March (2)

public Person(){
November (1)
name = "Default Abhi";

}
October (1)

public String getName() {

March (1)
return name;

February (1)
}


November (3)
public void setName(String name) {

this.name = name;
October (7)
}

September (5)

August (2)
/******************* PersonTestConstructor.java ***********/

public class PersonTestConstructor {


June (9)
May (29)
@Test

public void testGetName() {


April (1)
new MockUp<Person>() {

@Mock
September (1)
public void $init() {

//Dont assign name variable at all


June (1)
//Leave it null

May (1)
}

April (1)
};


March (2)
Person p = new Person();

String name = p.getName();


November (1)

October (1)
assertNull("Name of person is null",name);

}
June (2)

Here we have a class Person whose default constructor initializes the name variable to "Default Abhi" In the test
class PersonTestConstructor, I mock the constructor by using a special mock method $init to do nothing.

Remember the to put the @Mock  annotation above. I have spent hours trying to debug only to find out that I forgot.

How to mock constructors with parameters (or those that


take arguments) ?

Again we use $init to mock the constructor but this time with parameters.

/************************* Person.java ****************/

public class Person {

private String name;

public Person(String name){

this.name = name;

public String getName() {

return name;

public void setName(String name) {

this.name = name;

/******************* PersonTestConstructor.java ***********/

public class PersonTestConstructor {

@Test

public void testGetName() {

new MockUp<Person>() {

@Mock

public void $init(String name) {

//Dont assign name variable at all

//Leave it null

};

Person p = new Person("AbhiJMockit");

String name = p.getName();

System.out.println(name);

assertNull("Name of person is null",name);

How to mock static initialization blocks in JMockit?


This time the method to be used is $clinit. If you are bored with Person and Employee classes by now, we'll test
the Bank class this time.

In the following example the static initialization block calls a static method and sets the bankBalance to 100. But in
our test case we want to start off with 500.

Note the $clinit method in the BankTest class that calls the same method with 500 as the argument.

/***************** Bank.java ******************/

public class Bank {

static int balanceAmount;

//Static block begins

static {

updateBalance(100);

public static void updateBalance(float balance) {

balanceAmount += balance;

/*********************** BankTest.java **********/

public class BankTest {

@Test

public void testBankStaticBlock(){

new MockUp<Bank>(){

@SuppressWarnings("unused")

@Mock

public void $clinit(){

Bank.updateBalance(500);

};

assertEquals("The balance amount is 500", 500, Bank.balanceAmount);

How to mock public methods in JMockit?


There are two ways to can do it: 

  1. Behaviour Based Testing or using the Expectations class.


  2. State Based Testing using the MockUp apis.

We'll see both of them below. First using the Expectations class

1. Behaviour Based Testing or using the Expectations class.

In this technique we will be creating a Expectations anonymous inner class and define the expected behaviour
when a method is invoked with particular arguments. 

Lets continue with the Bank example. 

This time the Bank class uses the DBManager to retrieve the Account Holder Name to process the account. 

The Bank's processAccount() method takes in an Account ID and passes it onto the DBManager's
retrieveAccountHolder() method  to get the name from the DB and returns the same.

However we want to mask all the DB related code and return a name, say "Abhi"
when retrieveAccountHolder() is invoked with the Account ID as 10. 

The code to achieve all this is given below...

/**************** DBManager.java *************/

public class DBManager {

public String retrieveAccountHolderName(int accountId ){

String accountHolderName = null;

//connect to db

//retrieve the Account Holder Name

return accountHolderName;

/**************** Bank.java ****************/

public class Bank {

DBManager dbManager =new DBManager();

public String processAccount(int accountID){

//Some other code goes here

String accountHolderName = dbManager.retrieveAccountHolderName(accountID);

//some more processing code

return accountHolderName;

/*************** BankTest.java ****************/

public class BankTest {

@Test

public void testRetrieveAccountHolderName() {

Bank bank = new Bank();

// Define the Expectations block here

new Expectations() {

DBManager dbManager; // variables declared here are mocked by default

dbManager.retrieveAccountHolderName(10);

returns("Abhi");

};

String name = bank.processAccount(10);

assertEquals("Account holder Name for A/C id 10 is 'Abhi' ","Abhi",name);

Notice the DBManager is declared within the Expectations class and is mocked by default. However if you wanted to
declare it outside the test method then it should be annotated with the @Mocked annotation.

Now quick trivia!

What would have happened if I placed the Bank bank = new Bank() after the

expectations block?  Any Guesses?

The answer is - "The Test would have failed because of UnexpectedInvocation Exception" Why ? The reason
- Expectations is a strict checking mechanism. Placing the creation of Bank object after the Expectations block
would have called the constructor of DBManager. But in the Expectations block we have strictly mentioned that :

1. Only retrieveAccountHolderName() method  has to be called on the dbManager object in the following
code.
2. AND the argument MUST  be 10. Anything other that 10 will throw the same 
UnexpectedInvocation
Exception. Try this yourself.
3. AND the method retrieveAccountHolderName() can be invoked only once!

But then, our test cases may not be so rigid. In that case use the NonStrictExpectations class.

It places no restrictions on the number of times the mocked method is called or if any other method of the same
object is called. Most of the time you will be using NonStrictExpectations class.

One last tip before we move onto the MockUp apis. In the previous section point number 2 states that the argument
passed must be 10.

What to do if we require, when any integer is passed into the retrieveAccountHolderName() as an argument

You might also like