Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hierarchy of modules in guice

Tags:

guice

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.

like image 200
nes1983 Avatar asked May 24 '10 21:05

nes1983


1 Answers

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.

like image 90
ColinD Avatar answered Nov 03 '22 16:11

ColinD