Testing MyBatis Type Handlers

by andrew | 27th October 2010
Tagged:

Testing MyBatis Type Handlers
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!

Leave a Reply

Name (Required)

Email (Required - will not be published)

Website

Message (Required)