XNSIO
  About   Slides   Home  

 
Managed Chaos
Naresh Jain's Random Thoughts on Software Development and Adventure Sports
     
`
 
RSS Feed
Recent Thoughts
Tags
Recent Comments

Playing with EasyMock

I just started using EasyMock on my current project. So far, I have not used it much, but I think it would be helpful to some people to put some basic notes on my approach to using easymock.

I started playing around with JDBCFixture (A set of useful fixtures for Fitnesse). I was happy to see JDBCFixture using easymock for some of the JDBC stuff. I think this would be a good starting point for someone to understand easymock.

Lets consider a simple DeleteFixture. Following is the behavior that is expected on a DeleteFixture

1.Given a tableName, it should delete all the rows from the table

fitnesse.jdbc.DeleteFixture aTable

2.Given a tableName and where clause, it should execute the delete statement

fitnesse.jdbc.DeleteFixture aTable
where id=1

The core functionality of the DeleteFixture is basically to extract the correct data (tableName and the where clause) and form the corresponding SQL, which it can then execute on the database through the JDBC calls.

So we are interested to test the following sequence for the first scenario: (just TableName is given)
1.get a connection instance
2.connection.prepareStatement(“delete from tableName“) is called. We are not interested in how the sql is formed
3.preparedStatement .executeUpdate() is called
4.preparedStatement.close() is called
5.connection.close() is called

So what would a unit test for DeleteFixture look like?
Unfortunately with simple JUnit this kind of testing is not possible. So what do we do? You guessed it right, we use Mocks.

Using easyMock, the test class would like this:

package fitnesse.jdbc;

import fit.Fixture;
import fit.Parse;

import junit.framework.TestCase;

import org.easymock.MockControl;

import java.sql.Connection;
import java.sql.PreparedStatement;

public class DeleteFixtureTest extends TestCase {
private Connection connection;
private MockControl mockConnectionControl;
private MockControl mockStatementControl;
private PreparedStatement statement;

protected void setUp() throws Exception {
super.setUp();
JdbcConnectionFixture.driver = “org.gjt.mm.mysql.Driver“;

mockConnectionControl = MockControl.createControl(Connection.class);
connection = (Connection) mockConnectionControl.getMock();

mockStatementControl = MockControl.createControl(PreparedStatement.class);
statement = (PreparedStatement) mockStatementControl.getMock();
}

protected void tearDown() throws Exception {
mockConnectionControl = null;
mockStatementControl = null;
connection = null;
statement = null;
super.tearDown();
}

public void testJdbcCallSequenceForJustTableName() throws Exception {
JdbcConnectionFixture.setConnection(connection);

connection.prepareStatement(“delete from tableName“);
mockConnectionControl.setReturnValue(statement);

statement.executeUpdate();
mockStatementControl.setReturnValue(1);

statement.close();
connection.close();

replay();

Parse table = new Parse(”

fitnesse.jdbc.DeleteFixture tableName

“);
Fixture fixture = new Fixture();
fixture.doTables(table);

verify();
}

private void replay() {
mockConnectionControl.replay();
mockStatementControl.replay();
}

private void verify() {
mockConnectionControl.verify();
mockStatementControl.verify();
}

}

Let‘s start from the setUp() method:

MockControl mockConnectionControl = MockControl.createControl(Connection.class);
Connection connection = (Connection) mockConnectionControl.getMock();

MockControl.createControl() takes a parameter of type Class. We can pass Class, Abstract Class or even Interfaces. This would return the MockControl object.

mockConnectionControl.getMock() returns the actual mock object.

Now let‘s look at our actual test method

public void testJdbcCallSequenceForJustTableName() throws Exception {
JdbcConnectionFixture.setConnection(connection);

connection.prepareStatement(“delete from tableName“);
mockConnectionControl.setReturnValue(statement);

statement.executeUpdate();
mockStatementControl.setReturnValue(1);

statement.close();
connection.close();

replay();

Parse table = new Parse(”

fitnesse.jdbc.DeleteFixture tableName

“);
Fixture fixture = new Fixture();
fixture.doTables(table);

verify();
}

In the first statement JdbcConnectionFixture.setConnection(connection); we are injecting our mock connection into the system.

In the following calls we are setting the expections:

connection.prepareStatement(“delete from tableName“);
mockConnectionControl.setReturnValue(statement);

statement.executeUpdate();
mockStatementControl.setReturnValue(1);

statement.close();
connection.close();

Please note that this is the sequence of JDBC calls we expect. One can this of this as if we are recording a macro.

The replay() call tells the system that we have finished recording, following will be the actual execution. Hence after the replay() we call the actual method call that we want to test.

Parse table = new Parse(”

fitnesse.jdbc.DeleteFixture tableName

”);
Fixture fixture = new Fixture();
fixture.doTables(table);

Finally we call the verify() method, which checks if the macro recording sequence was same as the actual method call sequence with the expected paramter values.

Testing with Mocks using EasyMock can be as simple as this.


    Licensed under
Creative Commons License