Monday, May 24, 2010

The Google Web Toolkit (GWT) has a fairly simple infrastructure for managing internationalization. While there are a number of different options, the easiest one to use is called Static String Internationalization The basic idea is that you create a properties file for each language and GWT's deferred binding process creates an instance of a Interface which will be loaded depending on the locale. It works something like this:

Create a properties file (e.g. FooConstants.properties). This will contain definitions of the form bar=A string that I want to i18n.

Use the i18nCreator script to generate the Interface definition: i18nCreator -eclipse Foo com.example.foo.client.FooConstants

The problem with this is that calling GWT.create from within your code makes it difficult to unit test. If your code calls this directly then you will have to create your unit tests using GWT's Junit3 hack. Running unit tests this way is very slow, and I find it much better to try and factor out as much GWT specific code as possible so that you can write normal boring tests (for example using JUnit 4, or using mocks, or whatever else that GWT tests don't support that takes your fancy). The trick is that if you have any code that relies on an instance of these Constants/Messages files then you are screwed. The solution is to use a DynamicProxy to generate an instance of the interface and then inject these into your code. First we need to refactor our class to have the Constants interface injected, e.g:

Next we need to write some code to generate the constants. When the i18nCreator generates the interface it helpfully annotates it with the default text it needs. We can exploit this to generate an instance for testing: