Let me try first a quick answer, then we can iterate over details if you'd
like.

The use of Modules.override() here is what gives the ability to mock a set
of components that effectively represent interfaces to those components from
a system.  For example, if you have something like:

class MakesRpcCalls {
  @Inject MakesRpcCalls(
     RpcInterface rpcInterface) {
   ...
  }

  RpcResponse makeRpc(RpcRequest rpcRequest) {
      ... do some stuff
     return rpcInterface.call(rpcRequest);
  }
}

You might want to mock RpcInterface in your test.

Imagine the module that binds this interface in production looks like:

public class RealRpcInterfaceModule extends AbstractModule {
  @Override protected void configure() {
     bind(RpcInterface.class).to(RealBackendServiceInterface.class);
     ...
  }
}

And your application module might then install it:

public class ApplicationModule extends AbstractModule {
  @Override protected void configure() {
     install(new RealRpcInterfaceModule());
     ....
  }
}

And your main() method might look like:

public static void main(String[] args) {
  Injector injector = Guice.createInjector(new ApplicationModule());
  Server server = injector.getInstance(Server.class);
  server.runForever();
}

In an integration test, you'd want to be able to do something like start
this server pointing at a mock rpc backend.  One way to do this is to add
another method:


public static void main(String[] args) {
  // imagine 'EmptyModule' is one with no bindings.  thus, by default,
  // don't override any bindings within 'ApplicationModule'
  programmaticMain(args, new EmptyModule());
}

/**
  * Accepts the args from the command line and an {@code overrideModule},
the
  * bindings in which are used to override bindings in the {@link
ApplicationModule}.
  */
public static void programmaticMain(String[] args, Module overrideModule) {
  Module moduleToUse = Modules.override(new
ApplicationModule)).with(overrideModule);
  Injector injector = Guice.createInjector(moduleTouse);
  Server server = injector.getInstance(Server.class);
  server.runForever();
}

In your integration test, you'd then start a server with:

Server.programmaticMain(<args>, new AbstractModule() {
  @Override protected void configure() {
     bind(RpcInterface.class).to(MockedOutRpcInterface.class);
   }
}

Of course many variations on this theme exist, but the gist of overriding
production bindings remains the same.

Fred

On Thu, Aug 18, 2011 at 12:13 PM, Nathandelane <[email protected]>wrote:

> For a long time I have been working on a series of automated tests
> that rely on the creation of mocks through a service lookup utility
> (like Spring framework's), which in some ways resembles a dependency
> injection framework and is used like a DI framework, but it doesn't
> quite work the same way, and it has some intricacies that make it less
> reliable for DI in my opinion. Recently I've been trying to implement
> the usage of Guice in place of this service lookup utility, and I've
> been running into a possible issue that I can't seem to figure out. I
> however suppose that I must be missing something in relation to Guice.
>
> Essentially there are cases when we mock portions of a system and set
> them up in advance of running that system. Our service lookup utility
> in this sense seems to be global. In Guice however there seems to be a
> requirement of concrete implementations of AbstractModule or more
> correctly the Module interface. It seems to me that all of the
> examples provided use those implementations explicitly right before
> requesting an instance of an interface in question. If this is the
> case, then how would I implement my integration tests using Guice to
> mock certain portions of a system in advance of calling that system,
> and ensure that my mocks (in a Module implementation) get used? There
> isn't any way to do this is there? Because Guice isn't global, or
> rather the bindings aren't global to the test application or
> application under test, rather they are local.
>
> This is probably a special situation. Can anybody please help me
> clarify this point?
>
> Thanks.
>
> Nathan Lane
>
> --
> You received this message because you are subscribed to the Google Groups
> "google-guice" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/google-guice?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-guice?hl=en.

Reply via email to