Тест JUnit с инжекцией GIN, без GWTTestCase и перегрузки модулей джина?

Я разработал новый проект, используя Guice /Gin, чтобы я мог сделать наш код более модульным и способным к обмену, особенно при тестировании.

Однако я не могу выяснить, как заставить это работать на практике. У меня сложилось впечатление, что я могу просто создать новый модуль Gin /Guice в моем тесте и установить свой "базовый" модуль, перегружая любые привязки, которые я хочу заменить конкретными реализациями тестирования.

Я не хочу использовать GWTTestCase и загружать весь мой модуль, потому что он очень медленный и не требующий упрощения для тех типов гранулярного тестирования, которые мне нужны.

Я пытался использовать Jukito ( http://code.google.com/p/jukito/), gwt-test-utils ( http://code.google.com/p/gwt-test-utils/wiki/HowToUseWithGIN) а также некоторые ресурсы о том, как сделать это с помощью хитрости ( http://fabiostrozzi.eu/2011/03/27/junit-tests-easy-guice/).

Ни один из этих методов не дает никаких результатов.

Я думаю, что подход Guice мог бы работать, если бы я определил зеркальный модуль guice для моего модуля Gin. Однако я действительно не хочу управлять обоими из них. Я действительно просто хочу протестировать мой модуль GIN, как будто я предполагаю, что люди тестируют с Guice.

Я чувствую, что это должно быть действительно просто, может кто-нибудь указать мне примеры, которые работают?

Обновить

Другой способ взглянуть на этот вопрос:

Как заставить примеры на сайте Jukito ( http://code.google.com/p/jukito/) работать, когда вводимые мной классы находятся во внешнем модуле Gin?

** Обновление - в связи с ответом Томаса Бойера **

Спасибо за подсказку, Том, мне не удалось найти примеры использования адаптера, но я все равно попытался увеличить примеры Jukito для использования GinModuleAdapter:

@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);
  }
}

Когда я попытался запустить этот тест, я получил это исключение:

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)

Мой модуль gin является частью проекта GWTP и выглядит так:

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);

    }

}

Как вы можете видеть, класс, который я добавляю в моем тесте SyncedDOMModel, использует WebSocket который я связываю в моем модуле. Когда я тестирую, я не хочу использовать настоящий веб-сокет и сервер. Поэтому я хочу перегрузить эту привязку в моем тесте классом, который в основном имитирует все это. В этом случае проще внедрить другую реализацию WebSocket, чем использовать насмешку.

Если это поможет, это базовая схема класса SyncedDOMMOdel:

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

 ....
}

1 ответ

Решение

Вы можете использовать GinModuleAdapter использовать любой GinModule как Guice Module,

Очевидно, что вы не сможете воспользоваться специфическими функциями GIN: по умолчанию GWT.create() когда что-то не имеет конкретной привязки (это включает интерфейсы и абстрактные классы, которые будут выбрасывать в Guice), и автоматически искать RemoteService интерфейс, когда интерфейс, имя которого заканчивается Async не имеет конкретной привязки.
И вы не сможете использовать что-либо, что зависит от JSNI или отложенной привязки (GWT.create()), как в любомGWTTestCase модульный тест.

Другие вопросы по тегам