tags:

views:

113

answers:

2

Hi,

I'd like to run a unit test where a constant is slightly different than in the standard version. That is, in my default module, the following is

bindConstant().annotatedWith(Names.named("number of players")).to(4);

but in testing, I'd like to try this line instead:

bindConstant().annotatedWith(Names.named("number of players")).to(2);

Id like to achieve that without copying all of the rest of the module. What I really want is a "default" module that is "below" a more specialized module, such that in case of conflict, the specialized module wins (instead of throwing an exception, which is what guice does).

In essence, my question is: how does anybody arrange for more than one module without lots of code duplication?

Update: I've realized that the solution is really to use a factory, rather than a constant in THIS use case. I'd still be interested to learn if there's something like hierarchies of modules in general, though.

A: 

For my own use case, I think the solution is to use a factory and not a constant. I'd still be interested in a general answer, though, but for information only :).

nes1983
+3  A: 

Typically when using Guice properly, you shouldn't need to use Guice at all in tests (particularly unit tests... integration and end-to-end tests, yes). Anyway:

I'm not sure I understand what you're trying to do or what the issue is exactly but... you realize that when creating an Injector you can provide any number of Modules to it, right? That's a key part of using Guice. Make the modules as course or fine-grained as you want. You could have a NumberOfPlayersModule that only has that one binding, and then use a different module with a different binding instead sometimes (like for your test). You could also make a module that takes a constructor argument and create the module as new NumberOfPlayersModule(4) or new NumberOfPlayersModule(2) as you like.

There's also another feature of Guice that lets you override bindings in one or more modules with bindings from one or more other modules. That works like this:

// FooModule is your module that contains the "number of players" binding and
// some others

Module override = Modules.override(new FooModule())
   .with(new AbstractModule() {
      protected void configure() {
         bindConstant().annotatedWith(Names.named("number of players")).to(2);
      }
   });
Injector injector = Guice.createInjector(override);
// The int @Named("number of players") for the injector is 2

As you can see, there are really quite a lot of ways to make configuring your application different ways easy.

ColinD
Override! That's precisely what I wanted! Thank you!
nes1983