Professional Documents
Culture Documents
return accountHolderName;
return accountHolderName;
@Test
new Expectations() {
dbManager.retrieveAccountHolderName(10);
returns("Abhi");
};
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.
What would have happened if I placed the Bank bank = new Bank() after the
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.
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.
//connect to db
return accountHolderName;
return accountHolderName;
@Test
new MockUp<DBManager>() {
@SuppressWarnings("unused")
@Mock
return "Abhi";
};
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
return iAmPrivate();
@Test
new Expectations(simple){
Deencapsulation.invoke(simple, "iAmPrivate");
};
return iAmPrivate();
@Test
new MockUp<Simple>(){
@Mock
String iAmPrivate(){
};
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.
return "ORIGINAL";
//goes here
if(conStr.equals("ORIGINAL"))
return "SUCCESS";
else
return "FAIL";
@Test
new NonStrictExpectations(){
DBManager dbManager;
DBManager.getConnectionString();
returns("DUPLICATE");
};
assertEquals("Status is FAIL","FAIL",status);
return "ORIGINAL";
//goes here
if(conStr.equals("ORIGINAL"))
return "SUCCESS";
else
return "FAIL";
@Test
new MockUp<DBManager>(){
@Mock
return "DUPLICATE";
};
assertEquals("Status is FAIL","FAIL",status);
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.