Заставить 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)


arrow_upward
6
arrow_downward

Зачем вообще использовать 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