2

I've got a project that has gwt-log logging lines scattered throughout. Now I'm trying to write some unit tests and nothing seems to be working.

Any class I test that uses the gwt-log facility causes the following exception to be raised:

Caused by: com.googlecode.gwt.test.exceptions.GwtTestConfigurationException: 
A custom Generator should be used to instanciate 
'com.allen_sauer.gwt.log.client.LogMessageFormatter', 
but gwt-test-utils does not support GWT compiler API, 
so you have to add our own GwtCreateHandler with 
'GwtTest.addGwtCreateHandler(..)' method or to declare your 
tested object with @Mock

I have no need for the logger to function during unit tests, I'd prefer to mock it away. I've attempted to use Mockito to mock the logger, in a few different ways... obviously I have no idea what I'm doing here, none of the following code snippets helped the situation:

public class ClockTest extends GwtTest {
    @Mock private LogMessageFormatter lmf;
...

or

...
@Before
public void init() throws Exception {
    LogMessageFormatter lmf = mock(LogMessageFormatter.class);
...

Any clues on how to work this out would be most appreciated!

holocron
  • 312
  • 1
  • 3
  • 12

3 Answers3

2

Colin is right, you have 2 ways to deal with your error :

1) Mock the LogMessageFormatter, or at a higher level, mock your Logger instance. gwt-test-utils provides a simple API for mocking with both Mockito or EasyMock : http://code.google.com/p/gwt-test-utils/wiki/MockingClasses

2) provide your own GwtCreateHandler to instanciate the LogMessageFormatter, or at a higher your own Logger instance. Internally, gwt-log relies on GWT's deferred binding to instanciate a LogMessageFormatter object based on your configuration, which is parsed at compile time. It use GWT's generator API to create the LogMessageFormatter class, but gwt-test-utils is not able to use those kind of Generators. You'll have to do it "by hand", with gwt-test-utils deferred binding support : GwtCreateHandlers. Your "LoggerGwtCreateHandler" could use JDK's InvocationHandler and Proxy classes to write a proxy for the Logger interface which would simply silent each method call, since I guess you won't care about any log call in your tests.

Here is a discussion on how to write a GwtCreateHandler : https://groups.google.com/forum/?fromgroups#!topic/gwt-test-utils-users/r_cbPsw9nIE

Gael
  • 151
  • 5
1

From the error message you posted:

you have to add our own GwtCreateHandler with 
'GwtTest.addGwtCreateHandler(..)' method or to declare your 
tested object with @Mock

These are the two options you have to proceed. I've only just begun to work with gwt-test-utils, but the main premise is that it doesn't run the GWT compiler or Dev Mode, so it needs other ways to handle implementing 'magic' features like GWT.create. Its method is to either require you to mock the instance (this should be a fairly common idea in most of your tests for other objects involved in testing) or to provide something like a generator, and hook it up using GwtTest.addGwtCreateHandler.

Building a mock logger shouldn't be too bad, nor should implementing GwtCreateHandler - you just need to make something that has all the log methods. If you want the logging to work, then those methods need to actually invoke some other logger, like java.util.Logger, log4j, slf4j, etc but that is not required for just getting the tests to run (but may be handy for making sure that you logging works, or finding out why your test is failing.

Colin Alworth
  • 17,801
  • 2
  • 26
  • 39
  • Colin, thanks for the reply. I would definitely like to mock the logger but the concept is entirely new to me. Please see my edits above (when I get them in) and confirm that I'm on the right track. – holocron Apr 22 '12 at 03:37
  • There is a LogMessageFormatterGenerator.class file included in the gwt-log.jar... could this be used to provide a generator? And if so, how is it done? :) Thanks Colin, this is the 2nd time you've come to my rescue – holocron Apr 22 '12 at 04:10
1

for those still in pain with this damn problem here is what I managed to get (With a lot of pain too ...). It'll solve the conflict between Gwt-test-utils and Gwt-log.

You're of course welcome to modify the format method ;) :

@Before
public void correctLog() {
    this.addGwtCreateHandler(new GwtCreateHandler() {
        @Override
        public Object create(Class<?> classLiteral) throws Exception {
            if (classLiteral.isAssignableFrom(LogMessageFormatter.class)) {
                return new LogMessageFormatter() {
                    @Override
                    public String format(String logLevelText, String category,
                            String message, Throwable throwable) {
                        return message + " : " + throwable.getLocalizedMessage();
                    }
                };
            }
            return null;
        }
    });
}
Michael Laffargue
  • 10,116
  • 6
  • 42
  • 76