Tuesday, 19 May 2009

DbUnit and nullable columns

We use DbUnit for our database integration tests and this works very well allowing us to populate the database with test data specific for the test at hand.

I have had a problem for the last few hours that has driven me to distraction. I was populating a table with a row and the tests using this data were all OK.

I then added an extra row that also wanted to populate an extra nullable column. The test failed because the test thought this column was null. I stopped the test in the debugger and yes the code was correct, the column was null. What could be wrong ?

My DbUnit XML looked like this:
<dataset>
<MY_TABLE
ID="1"
MANDATORY_COL="This column must have data"
/>

<MY_TABLE
ID="2"
MANDATORY_COL="This column must have data"
NULLABLE_COL="This column is nullable"
/>
</dataset>


The problem appears to be that DbUnit builds its list of columns from the first occurrance of each table. Any optional columns listed in subsequent entries are simply ignored.

There are two solutions. Either reverse the order of the two items in the XML file, or set the column to null in the rows where the nullable column is not required.

Friday, 15 May 2009

TDD Testing of Dependancy Injection in Spring

Spring relies very heavily on dependancy injection and when writing integration tests the first thing that must work before you even try to connect to things like your database is that all your beans must be correctly injected.

So before I get all excited and start writing tests that read or write to the database I write a very simple test to check that everything has been injected correctly.

public class FooServiceIntegrationTest extends BaseIntegrationTester{
private FooService fooService;

public void setFooService(BulkUploadService aFooService){
fooService = aFooService;
}

public void testInjection() throws Exception{
assertNotNull("FooService not injected", fooService);
}
}

Strictly speaking this test testInjection is not needed at this stage because the test will fail if the injection of this primary bean fails.

Ok so I need to create the bean.

<bean id="fooService" name="fooService" class="uk.co.foo.FooServiceImpl">
</bean>

The test will now pass.

The test now gets more useful as I now extend the test to see if FooService has its beans injected successfully.

public class FooServiceIntegrationTest extends BaseIntegrationTester{
private FooService fooService;

public void setFooService(BulkUploadService aFooService){
fooService = aFooService;
}

public void testInjection() throws Exception{
assertNotNull("FooService not injected", fooService);
assertNotNull("FooService not injected", fooService.getBarDao());
}
}

Now this will not compile at first as fooService.getBarDao() does not exist.
I add this to the interface and implement the method and re-run the test,

The test fails as we have not set the property on the bean so lets do that.

<bean id="fooService" name="fooService" class="uk.co.foo.FooServiceImpl">
<property name="barDao" ref="barDao" />
</bean>

Assuming barDao has also been configured then the test will now pass.

Possibly others do this, I do not know but I have found this little test invaluable as a precursor to grander integration tests later on.

BTW BaseIntegration tester does little more than extend AbstractTransactionalDataSourceSpringContextTests and implement the method getConfigLocations()

Thursday, 14 May 2009

Eclipse Hot Keys and the language bar on Windows

I like to use Eclipse Hot Keys and two of my favourites are Ctrl+Shift+R (open a resource) and the very similar Ctrl+Shift+T.

Sometimes when in eclipse I would do something and suddenly find the double quote and '@' keys (among others) had swopped.

I sussed out that somehow I was changing my keyboard settings from English UK to English US. I left it at that now I knew I could fix it.

Today I sussed out why and how to stop it happening again.

The hot keys to change the language is Ctrl+Shift and I must have been missing off the R or T.

So assuming you do not want to change the keyboard from one to the other at all or not too often you have two options:
a) disable the hot keys
b) remove the language you do not want.

To do this go to: Contol Panel->Regional & Language options->Languages->Details.

If you want to disable the hot keys select Key Settings->'Change Key Sequence'.
If you want to remove one of the languages, select one and then select 'remove'