You are on page 1of 5

//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


the return string should be "Abhi"? For this JMockit provides us with a field called anyInt.   The
line dbManager.retrieveAccountHolderName(10) should be replaced
with dbManager.retrieveAccountHolderName(anyInt). We will look into more of this in this section.

2. State Based Testing using the MockUp apis.

If you have already read "How to mock constructors in Jmockit?" you would have seen the MockUp class in action.

MockUp apis are categorized as State Based testing because the mocks you write are not dependent on the
behaviour of the test class. They are defined independently and work the same in any case.

In the code below observe how the MockUp class redefines the
method retrieveAccountHolderName() of class DBManager.

This is a great utility if only some methods of a class need to be redefined.

/**************** 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 testBankProcessAccount() {

new MockUp<DBManager>() {

@SuppressWarnings("unused")

@Mock

public String retrieveAccountHolderName(int accountId ){

return "Abhi";

};

Bank bank = new Bank();

String name = bank.processAccount(20);

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

How to mock private methods in JMockit?


Pretty cool, isn't it? To be able to modify private methods?
The follwing two examples will give you how a private method is redefined first by using the Expectations api and
then the MockUp api.

First the Expectation API.  Yes of course, we can't call the private method directly in our Test class. BUT JMockit
offers a neat Reflection Utility called the Deencapsulation class.

This class has static methods that can invoke private methods and access private fields.More about it later

The Expectations Way

/****************** Simple.java ***********/

public class Simple {

private String iAmPrivate(){

return "Private Method";

public String publicCallsPrivate(){

return iAmPrivate();

/**************** SimpleTest.java *********/

public class SimpleTest {

@Test

public void testPublicInvokesPrivate(){

//Make simple final to be used in the Expectations inner class

final Simple simple = new Simple();

//pass simple as argument to make it a Mocked type

//in the Expectations class

new Expectations(simple){

Deencapsulation.invoke(simple, "iAmPrivate");

returns("I got INVOKED");

};

String str = simple.publicCallsPrivate();

assertEquals("The returned string is - I got INVOKED","I got INVOKED",str);

Now for the MockUp way

/****************** Simple.java ***********/

public class Simple {

private String iAmPrivate(){

return "Private Method";

public String publicCallsPrivate(){

return iAmPrivate();

/**************** SimpleTest.java *********/

public class SimpleTest {

@Test

public void testPublicInvokesPrivateMockUp(){

new MockUp<Simple>(){

//Override the private method

//Dont provide any ACCESSS MODIFIER!

@Mock

String iAmPrivate(){

return "MockUp Invoke";

};

Simple simple = new Simple();

String str = simple.publicCallsPrivate();

assertEquals("String returned - MockUp Invoke","MockUp Invoke",str);

How to mock static methods in JMockit?


Again we will see how to mock a static method by using the Expectations and MockUp apis.

The Expectations Way

The only thing to be done is to mark the field in the test class with @Mocked or create a local variable in the
anonymous Expectations class.

Lets go back to the Bank example. Our Bank class has a method called makeConection() that internally calls
DBManager's getConnectionString() static method. However when we write the test method we want the
getConnectionString() to return altogether a different String.

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

public class DBManager {

public static String getConnectionString(){

return "ORIGINAL";

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

public class Bank {

public String makeConnection(){

//some connection related code

//goes here

// call to static method

String conStr = DBManager.getConnectionString();

// If the connection String

// is anything other than

// ORIGINAL return FAIL

if(conStr.equals("ORIGINAL"))

return "SUCCESS";

else

return "FAIL";

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

public class BankTest {

@Test

public void testMakeConnection(){

new NonStrictExpectations(){

// DBManager is mocked here

DBManager dbManager;

DBManager.getConnectionString();

returns("DUPLICATE");

};

Bank bank = new Bank();

String status = bank.makeConnection();

assertEquals("Status is FAIL","FAIL",status);

Now For the MockUp Way.....

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

public class DBManager {

public static String getConnectionString(){

return "ORIGINAL";

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

public class Bank {

public String makeConnection(){

//some connection related code

//goes here

// call to static method

String conStr = DBManager.getConnectionString();

// If the connection String

// is anything other than

// ORIGINAL return FAIL

if(conStr.equals("ORIGINAL"))

return "SUCCESS";

else

return "FAIL";

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

public class BankTest {

@Test

public void testMakeConnectionWithMockUp(){

new MockUp<DBManager>(){

// Redefine the method here

// But With No static modifier

@Mock

public String getConnectionString(){

return "DUPLICATE";

};

Bank bank = new Bank();

String status = bank.makeConnection();

assertEquals("Status is FAIL","FAIL",status);

How to invoke or test private methods in JMockit?


If you have read the previous "How to"s, you already know the answer - its the Deencapsulation class.

There may be a private method you want to test. Generally if you read any article-they'll usually advise to move it to
more broader visibility. I personally wont agree to this.

If you are stuck with writing test methods for legacy code, you cant just refactor the code and check it in. The latter is
a mammoth process in itself.

Another option is to use the native reflection api's provided by java. I've tried this. It becomes a bowl of hot vegetable
noodles you wont be able to handle later on.

Back to Deencapsulation class! The most used methods are invoke() , setField() and the getField().

The names are pretty intuitive and you'll be using them all over your junits when dealing with private variables and
methods.

How to throw Exceptions in an Expectations block?

You might also like