Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

JUnit Testing Using EasyMock

DZone's Guide to

JUnit Testing Using EasyMock

EasyMock and JUnit can work together to make unit testing your Java code much easier through the use of proxy objects.

· Java Zone
Free Resource

Get the Edge with a Professional Java IDE. 30-day free trial.

JUnit is one of the most popular frameworks for performing Java UT. Mocking is also an aspect that goes hand in hand with JUnit. Unit testing is, of course, performed by developers to test the code they've written.

Let’s consider: 

  • Developer 1 has developed business logic code.

  • Developer 2 has developed persistence logic code (code that interacts with the database).

Image title


If Developer 1 has to use the persistence logic code (method call) written by Developer 2, then Dev 1 might mock that method call. Doing so will let the developer focus only on that code to test it. It’s more like staying in an environment and just testing the code in that environment itself.

While unit testing, developers just test the code in the same environment and mocks the interaction with any other environment.

A more real-time example would be where the code has to interact with the payment gateway. For UT, a developer might not want to send requests to the payment gateway.

Image title

Actual interactions with the payment gateway might be done during the SIT (System Integrated Testing ) phase.

There are many frameworks for mocking; Mockito and EasyMock are two of the most popular frameworks. I will be using EasyMock in the example below. Mocking is the process of using a fake object during the UT phase. These frameworks do this by generating proxy objects (java.lang.reflect.Proxy). However, for these purposes, you don't need to know the details about proxy objects. 

I will just be using a simple editor for the example, as it will allow for better understanding of the implementations that an IDE might not be able to show.

We will need following JARs:

  • mysql-connector-java-5.1.6-bin.jar   <Your JDBC driver, incase you don't mock>

  • junit-4.11-beta-1.jar

  • hamcrest-core-1.3.RC2.jar

  • easymock-3.2.jar

  • cglib-nodep-2.2.2.jar

  • objenesis-1.2.jar

There are four java files for this example.

  • Student.java (POJO Class)

  • StudentDAO.java

  • StudentCheck.java

  • StudentTest.java <JUnit Test Class>

Here, I am using the data type as String for rollNo (though ideally, it should be int). I'm just using a String for the sake of this example.

public class Student
{
    private String rollNo;
    private String firstname;
    private String lastname;
    private String dept;

    public String getRollNo(){
        return rollNo;
    }

    public void setRollNo(String rollNo){
        this.rollNo = rollNo;
    }

    public String getFirstname(){
        return firstname;
    }

    public void setFirstname(String firstname){
        this.firstname = firstname;
    }

    public String getLastname(){
        return lastname;
    }

    public void setLastname(String lastname){
        this.lastname = lastname;
    }

    public String getDept(){
        return dept;
    }

    public void setDept(String dept){
        this.dept = dept;
    }

    public String toString(){
        return "\n Roll No: "+rollNo+ "\n Firstname :" +firstname+ "\n Lastname : "+lastname+ "\n Dept : "+dept;
    }
}


This is the DAO class that actually hits the database.

import java.sql.*;
public class  StudentDAO{

    public Student getStudentDetails(String rollNo) throws Exception{

        System.out.println("Actual DB call will occur......");

        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/trial","root","root");
        PreparedStatement ps = con.prepareStatement("select * from Student where rollno=?");
        Student stud = new Student();
        ps.setString(1,rollNo);
        ResultSet rs= ps.executeQuery();
        while(rs.next()){
            stud.setRollNo(rs.getString("rollno"));
            stud.setFirstname(rs.getString("firstname"));
            stud.setLastname(rs.getString("lastname"));
            stud.setDept(rs.getString("dept"));
        }
        return stud;
    }
}


Please note that there is an SOP on line 6, which prints on the console if the code hits the database.

System.out.println("Actual DB call will occur......");


StudentCheck.java is the class that calls the getStudentDetails() method of the StudentDAO.java class.

public class  StudentCheck{

    private StudentDAO studDAO = null;

    public Student getDetails(String rollNo) throws Exception{

        System.out.println("Before DB Call");

        Student stud = studDAO.getStudentDetails(rollNo);

        System.out.println("After DB Call");
        return stud;
    }

    public void setStudDAO(StudentDAO studDAO){
        this.studDAO = studDAO;
    }
}


Now, StudentTest.java is the Test class where the actual action happens. This class has JUnit and the EasyMock API.

Image title


The EasyMock framework creates a proxy object/fake object of the class that we want to mock, and this proxy object can be used to return whatever you want as a return value of any of the methods of this class.

Image title


import static org.junit.Assert.*;
import org.junit.Test;
import org.easymock.*;

public class StudentTest {
    @Test
    public void testGetDetails001() throws Exception{
        String rollNo= "111";
        StudentDAO studentDAO = EasyMock.createMock(StudentDAO.class);
        Student student = new Student();
        student.setRollNo("111");
        EasyMock.expect(studentDAO.getStudentDetails(EasyMock.isA(String.class))).andReturn(student);
        EasyMock.replay(studentDAO);
        StudentCheck studentCheck = new StudentCheck();
        studentCheck.setStudDAO(studentDAO);
        Student stud = studentCheck.getDetails(rollNo);
        assertEquals("111",stud.getRollNo());
    }
}


We can compare an EasyMock object to a tape.

  • createMock(): Blank Tape.

  • expect(): Recording your favorite song.

  • replay(): Playing your favorite song.

  • reset(): Erasing the tape, making it blank to record a new song.

Image title


Here, we are using EasyMock.isA(), but if we expect that a specific input is to be received by the method that mock, then we can set such expectations

EasyMock.expect(studentDAO.getStudentDetails("111")).andReturn(student);


This ensures that getStudentDetails() is expected ONLY when the input to the method is "111." For anything else, we get an exception.

Image title


Finally, we run our test class with the following command.

Image title

Please note "Actual DB call will occur......" is not printed on the console. This shows the DB was not hit.

Get the Java IDE that understands code & makes developing enjoyable. Level up your code with IntelliJ IDEA. Download the free trial.

Topics:
junit ,easymock ,java ,unit testing ,tutorial

Published at DZone with permission of Sourabh Bawage. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}