Заставить FactoryModuleBuilder от Guice создать фабрику, возвращающую макет?

В моем приложении я использую FactoryModuleBuilder для автоматического создания экземпляров некоторого класса:

new AbstractModule() {
  @Override
  protected void configure() {
    install(new FactoryModuleBuilder().implement(A.class,B.class).build(A.AFactory.class));
  }
});

В моем тесте я действительно не хочу использовать реализацию (класс B), поэтому я хотел бы настроить модуль, чтобы фабрика возвращала макет Mockito следующим образом:

new AbstractModule() {
  @Override
  protected void configure() {
    install(new FactoryModuleBuilder().implement(A.class,myMockInstance).build(A.AFactory.class));
  }
});

Очевидно, что вышеизложенное не имеет смысла, потому что реализация () сообщает, какая реализация должна использоваться для интерфейса A, но я надеюсь, что это доказывает, что я хочу, чтобы созданная фабрика использовала мой фиктивный объект. Тогда я мог бы использовать свой макет, как обычно:

Mockito.when(myMockInstance.doStuff()).thenReturn(result);

Возможно ли это или мне нужно вручную создать класс C, реализующий A, который будет действовать как макет?


person Mateusz Dymczyk    schedule 21.10.2013    source источник


Ответы (1)


Зачем вообще использовать FactoryModuleBuilder? Он существует для автоматизации обработки @Assisted параметров от A.AFactory до B конструктора, но в тесте вам это не нужно, особенно если фабрика возвращает макет. Вместо этого смоделируйте свой собственный A.AFactory и сделайте его доступным через Guice.

final A myMockInstance = createAMock();
new AbstractModule() {
  @Override protected void configure() {}

  @Provides
  A.AFactory createAFactory() {
    A.AFactory factory = mock(A.AFactory.class);
    when(factory.createA(anyString(), anyInt(), any(Dependency.class)))
        .thenReturn(myMockInstance);
    return factory;
  }
});

Здесь я использую метод @Provides, но вы легко можете просто написать свой собственный пятистрочный файл с именем A.AFactory вместо этого и связать его с помощью bind(A.AFactory.class).to(AFactoryForTest.class) или настроить свою фиктивную фабрику в другом месте и bind(A.AFactory.class).toInstance(myMockInstance);.

person Jeff Bowman    schedule 21.10.2013
comment
да, я так и думал сделать, но мне не хватило ноу-хау Guice, спасибо :-) - person Mateusz Dymczyk; 22.10.2013