Guice tricks for better testability, part one

June 16, 2010

I thought I’d enumerate some of the small Guice tricks we use for making our code more testable. Today: Logical Clocks.

You never want to use System.currentTimeMillis() in your code. Rather, you want a logical clock that you can replace in your tests in order to control the flow of time. In Guice, not only can you inject instances of classes, but you can inject a Provider of an instance. (essentially a no-arg factory object, and if the instance type has a no-arg constructor, then you can get a Provider of that type without any explicit Guice bindings)

To bring it all together, you can think of a clock as a factory that produces the value of the current time. In your class you just inject the Provider:

class Foo {
  @Inject Provider<DateTime> clock;

  ...

  void doSomething() {
    DateTime now = clock.get();
  }
}

In production the above Provider would produce a new DateTime object each time the get() method is invoked. (because DateTime has a no-arg constructor with the right semantics)

And in your tests you could, for example, fix the current time using a Provider that always returns the same value:

Foo foo = new Foo();
// always returns this value
foo.clock = Providers.of(new DateTime(2010, 6, 15, 12, 0, 0, 0, 0, ET));