
When using MyBatis SQL Maps as your ORM framework, its very common to need to implement a type handler for any custom types/enums you want to persist.
These implementations can all look very similar and usually behave in a similar fashion and so it is an easy target for automating the unit testing to avoid confusion and mistakes though cut and paste*.
The Testing Class
package com.macbtech.blog.testing;
import java.sql.SQLException;
import org.easymock.EasyMock;
import org.easymock.IMocksControl;
import org.junit.Assert;
import com.ibatis.sqlmap.client.extensions.ParameterSetter;
import com.ibatis.sqlmap.client.extensions.ResultGetter;
import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;
public class SQLMapTypeHandlerTester<T> {
final private IMocksControl mockControl = EasyMock.createControl();
public void testHandler(final TypeHandlerCallback handler,
final T[] types,
final int nullType) throws SQLException {
testGetResults(handler, types);
testSetParameter(handler, types, nullType);
testSetValueOf(handler, types);
}
@SuppressWarnings("unchecked")
private void testGetResults(final TypeHandlerCallback handler,
final T[] types) throws SQLException {
final ResultGetter resultGetterMock = mockControl.createMock(ResultGetter.class);
EasyMock.expect(resultGetterMock.getString()).andReturn(null);
for (final T type : types) {
EasyMock.expect(resultGetterMock.getString()).andReturn(type.toString());
}
mockControl.replay();
Assert.assertNull("Expected null",handler.getResult(resultGetterMock));
for (final T type : types) {
Assert.assertEquals("Unexpected result", type,
(T)handler.getResult(resultGetterMock));
}
mockControl.verify();
mockControl.reset();
}
private void testSetParameter(final TypeHandlerCallback handler,
final T[] types,
final int nullType) throws SQLException {
final ParameterSetter parameterSetterMock =
mockControl.createMock(ParameterSetter.class);
parameterSetterMock.setNull(nullType);
for (final T type : types) {
parameterSetterMock.setString(type.toString());
}
mockControl.replay();
handler.setParameter(parameterSetterMock, null);
for (final T type : types) {
handler.setParameter(parameterSetterMock, type);
}
mockControl.verify();
mockControl.reset();
}
private void testSetValueOf(final TypeHandlerCallback handler,
final T[] types) throws SQLException{
Assert.assertEquals("Unexpected value of", null, handler.valueOf(null));
for (final T type : types) {
Assert.assertEquals("Unexpected value of", type,
handler.valueOf(type.toString()));
}
}
}
The Unit Test
@Test
public void testCustomTypeTypeHandler() throws SQLException {
SQLMapTypeHandlerTester<CustomType> customTypeTester = new SQLMapTypeHandlerTester<CustomType>();
customTypeTester.testHandler(new CustomTypeTypeHandler(), CustomType.values(), Types.VARCHAR);
}
* this has killed me too many times!
