Easy way to fill up ResultSet with data

DiaWorD picture DiaWorD · May 18, 2009 · Viewed 37.5k times · Source

I want to mock a ResultSet. Seriously. I'm refactoring one big complicated piece of code which is parsing data from ResultSet, and I want my code to behave identically. So, I need to write a unit test for the piece being refactored to be able to test this.

After googling I came up with 2 ideas:

  1. Use EasyMock, write looooong mocking sequence. VERY BAD solution: hard to add initial data, hard to change data, big test debugging promices.
  2. Use Apache Derby or HSQLDB to create in-memory DB, fill it from file or String array, query with some magical InMemoryDBUtils.query(sql). Then use that ResultSet. Unfortunately, I did not find any magical InMemoryDBUtils to write the test fast :-). IBM article "Isolated unit testing of persistence with Derby" seems just fine about what I need, though...

Second approach looks somewhat easier and much more supportable.

What would you advice for creating such a mock? (despite doctors, of course :-)? Am I missing an eyebrow some silver bullet? Possibly, DBUnit is the tool for this?

Answer

matt picture matt · May 18, 2009

I've had success with the MockResultSet class from here: http://mockrunner.sourceforge.net/. It allows you to create a class that implements the ResultSet interface, and lets you set the values for each column and row.

If your methods are working with ResultSets of reasonable size, you should be able to create tests that return the values you need fairly easily.

Here's a simple example:

MockResultSet rs = new MockResultSet("myMock");

rs.addColumn("columnA", new Integer[]{1});
rs.addColumn("columnB", new String[]{"Column B Value"});
rs.addColumn("columnC", new Double[]{2});

// make sure to move the cursor to the first row
try
{
  rs.next();
}
catch (SQLException sqle)
{
  fail("unable to move resultSet");
}

// process the result set
MyObject obj = processor.processResultSet(rs);

// run your tests using the ResultSet like you normally would
assertEquals(1, obj.getColumnAValue());
assertEquals("Column B Value", obj.getColumnBValue());
assertEquals(2.0d, obj.getColumnCValue());