Writing Custom DbUnit Data Types: Text Array
After we have finished this lesson, we:
- Can write a custom DbUnit data type which supports PostgreSQL text arrays.
- Know how we can ensure that DbUnit uses our custom data type.
This lesson assumes that:
Get the source code from Github
Creating Our DbUnit Data Set
We have to write integration tests for a repository which reads information from the products table. When we initialize our database into a known state, we have to set the value of the tags column which contains a text array. When we configure the value of this column in our DbUnit data set, the most obvious choice is to use a comma-separated value which specifies the tags of a product.
After we have created our DbUnit data set, it looks as follows:
1<dataset>
2 <products id="1"
3 product_description="Product description"
4 product_name="Product name"
5 tags="example,product"
6 />
7</dataset>
Next, we will find out how we can create a custom DbUnit data type which supports text arrays.
Writing Our Custom DbUnit Data Type
When we want to create a custom DbUnit data type, we have to create a new data type class and implement the typeCast() method of the DataType class. We can implement this method by following these steps:
- If the value given as a method parameter is a
Stringobject, transform the value into aStringarray and return the created array. - If the value given as a method parameter isn’t a
Stringobject, throw a new exception.
After we have implemented the typeCast() method, the source code of our data type class looks as follows:
1import org.dbunit.dataset.datatype.AbstractDataType;
2import org.dbunit.dataset.datatype.TypeCastException;
3
4public class StringArrayDataType extends AbstractDataType {
5
6 public StringArrayDataType(String name, int sqlType) {
7 super(name, sqlType, String.class, false);
8 }
9
10 @Override
11 public Object typeCast(Object value) throws TypeCastException {
12 if (value instanceof String) {
13 return ((String) value).split(",");
14 }
15
16 throw new IllegalArgumentException(String.format(
17 "Unsupported type. Expected String but was: %s",
18 value.getClass().getName()
19 ));
20 }
21}
Let’s move on and find out how we can enable our custom DbUnit data type.
Enabling Our Custom DbUnit Data Type
When we want to ensure that DbUnit uses our custom data type, we have create a new data type factory class and implement the createDataType() method of the IDataTypeFactory interface. We can implement this method by following these steps:
- If the data type of the processed column is text array, return a new
StringArrayDataTypeobject. - If the data type of the processed column is an unsupported array type, throw a new exception.
- Invoke the
createDataType()method of the super class and return the returned data type object.
After we have implemented the createDataType() method, the source code of our data type factory class looks as follows:
1import org.dbunit.dataset.datatype.DataType;
2import org.dbunit.dataset.datatype.DataTypeException;
3import org.dbunit.ext.postgresql.PostgresqlDataTypeFactory;
4
5import java.sql.Types;
6
7public class CustomPostgreSQLDataTypeFactory extends PostgresqlDataTypeFactory {
8
9 private static final String SQL_TYPE_NAME_TEXT_ARRAY = "_text";
10
11 @Override
12 public DataType createDataType(int sqlType,
13 String sqlTypeName,
14 String tableName,
15 String columnName) throws DataTypeException {
16 if (sqlType == Types.ARRAY) {
17 if (sqlTypeName.equals(SQL_TYPE_NAME_TEXT_ARRAY)) {
18 return new StringArrayDataType(sqlTypeName, sqlType);
19 }
20 throw new IllegalArgumentException(
21 "Unsupported array type: " + sqlTypeName
22 );
23 }
24
25 return super.createDataType(sqlType,
26 sqlTypeName,
27 tableName,
28 columnName
29 );
30 }
31}
We can now implement a custom DbUnit data type which supports PostgreSQL text arrays. Let’s summarize what we learned from this lesson.
Summary
This lesson has taught us two things:
- When we set the value of a database column which contains a text array, we should use a comma-separated value in our DbUnit data set.
- When we ensure that DbUnit uses our custom data type, we have to ensure that our data type factory returns a new
StringArrayDataTypeobject if the data type of the processed column is text array.