Domanda

I designed a new project using Guice/Gin so I could make our code more modular and swap-able especially when testing.

However, I am not able to find out how to make this work in practice. I was under the impression that I could just create a new Gin/Guice module in my test and install my 'base' module, overloading any bindings that I want to replace with specific testing implementations.

I don't want to have to use GWTTestCase and load my entire module, because it is very slow and unecissary for the types of granular testing I need to do.

I have tried using Jukito (http://code.google.com/p/jukito/), gwt-test-utils (http://code.google.com/p/gwt-test-utils/wiki/HowToUseWithGIN) and also some resources on doing this with guice (http://fabiostrozzi.eu/2011/03/27/junit-tests-easy-guice/).

None of these methods are yielding any results.

I think the Guice approach might work, if I defined a mirror guice module for my Gin module. However I really don't want to have to manage both of these. I really just want to test my GIN module like I would assume people test with Guice.

I feel like this should be really simple, can anyone point me to examples that work?

Update

Another way of looking at this question is:

How do I get the examples on the Jukito site (http://code.google.com/p/jukito/) work when the classes I am injecting are in an exernal Gin module?

**Update - In reference to Thomas Boyer's answer **

Thanks for the hint Tom, I was not able to find examples of using the adapter but I tried augmenting the Jukito examples to use the GinModuleAdapter anyway:

@RunWith(JukitoRunner.class)
public class MyGinTest {

  public static class Module extends JukitoModule {
    protected void configureTest() {
        install(new GinModuleAdapter(new ClientModule()));
    }
  }

  @Test
  @Inject
  public void testAdd(SyncedDOMModel mod){
      assertNotNull(mod);
  }
}

When I tried to run this test I recieved this exception:

java.lang.AssertionError: should never be actually called
    at com.google.gwt.inject.rebind.adapter.GwtDotCreateProvider.get(GwtDotCreateProvider.java:43)
    at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
    at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031)
    at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
    at com.google.inject.Scopes$1$1.get(Scopes.java:65)
    at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
    at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:204)
    at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:198)
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024)
    at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:198)
    at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:179)
    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:109)
    at com.google.inject.Guice.createInjector(Guice.java:95)
    at com.google.inject.Guice.createInjector(Guice.java:72)
    at com.google.inject.Guice.createInjector(Guice.java:62)
    at org.jukito.JukitoRunner.ensureInjector(JukitoRunner.java:118)
    at org.jukito.JukitoRunner.computeTestMethods(JukitoRunner.java:177)
    at org.jukito.JukitoRunner.validateInstanceMethods(JukitoRunner.java:276)
    at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:102)
    at org.junit.runners.ParentRunner.validate(ParentRunner.java:344)
    at org.junit.runners.ParentRunner.<init>(ParentRunner.java:74)
    at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:55)
    at org.jukito.JukitoRunner.<init>(JukitoRunner.java:72)

My gin module is part of a GWTP project, and looks like this:

public class ClientModule extends AbstractPresenterModule {

    @Override
    protected void configure() {
        install(new DefaultModule(ClientPlaceManager.class));

        bindPresenter(MainPagePresenter.class, MainPagePresenter.MyView.class,
                MainPageView.class, MainPagePresenter.MyProxy.class);

        bindConstant().annotatedWith(DefaultPlace.class).to(NameTokens.main);

        bindPresenterWidget(MapTreePresenter.class,
                MapTreePresenter.MyView.class, MapTreeView.class);

        bindPresenterWidget(MapTreeItemPresenter.class,
                MapTreeItemPresenter.MyView.class, MapTreeItemView.class);

        bind(ResourcePool.class).to(DefferredResourcePool.class);

        bind(WebSocket.class).to(WebSocketImpl.class);

    }

}

As you can somewhat see, the class I am injecting in my test SyncedDOMModel, uses a WebSocket which I bind in my module. When I am testing, I don't want to use a real websocket and server. So I want to overload that binding in my test, with a class that basically emulates the whole thing. It's easier to just inject a different implementation of the WebSocket in this case rather than use mocking.

If it helps, this is a basic outline of the SyncedDOMMOdel class:

public class SyncedDOMMOdel {
 ....
    @Inject
    public SyncedDOMModel(WebSocket socket){
        this.socket = socket;
    }

 ....
}
È stato utile?

Soluzione

You can use the GinModuleAdapter to use any GinModule as a Guice Module.

Obviously, you won't benefit from GIN's specific features: default to GWT.create() when something has no particular binding (this includes interfaces and abstract classes, which would throw in Guice), and automatically search for a RemoteService interface when an interface whose name ends Async has no specific binding.
And you won't be able to use anything that depends on JSNI or deferred binding (GWT.create()), as in any non-GWTTestCase unit test.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top