Как получить инжектор Guice для класса с параметризованным конструктором

#java #guice #guice-3

#java #guice #guice-3

Вопрос:

Сейчас я пишу следующий класс и тестовый код, и он работает нормально.

 public class AppleRegistry {
  private final ImmutableMap<String, Apple> appRegistry;
  
  AppleRegistry(Apple... apple) {
    this.appRegistry = createRegistry(apple);
  }

  @Inject
  AppleRegistry(
    Provider<GoodApple> goodAppleProvider,
    Provider<BadApple> badAppleProvider,
    Provider<BrandedApple> brandedAppleProvider) {
      this(goodAppleProvider.get(), badAppleProvider.get(), brandedAppleProvider.get());
    }
  
  private static ImmutableMap<String, Apple> createRegistry(Apple... apple){......}
  
  public Apple findApple(String key) {....}
}

public interface Apple{
...
}

public class GoodApple implements Apple {
  private final Producer producer;
  private final Suuplier supplier;

  @Inject
  GoodApple(Producer producer, Supplier supplier) {....}
....
}

public class BadApple implements Apple {.....}
public class BrandedApple implements Apple {....}

Test class
@RunWith(JUnit4.class)
@SmallTest
public class AppleRegistryTest {

  @Before
  public void setUp() throws Exception {
    Guice.createInjector().injectMemeber(this);
  }

  @Test
  public void testFindApple_emptyRegistry() {
    Optional<Apple> apple = new AppleRegistry().findApple("First");
    assertFalse(apple.isPresent());
  }
}
 

Пока все работает нормально, и тест проходит.
Теперь я хочу ввести новую зависимость в AppleRegistryClass
Вот изменения

 public class AppleRegistry {
 private final ImmutableMap<String, Apple> appRegistry;
 private final SystemHelper systemHelper;
      
 AppleRegistry(SystemHelper systemHelper, Apple... apple) {
    this.systemHelper = systemHelper;
    this.appRegistry = createRegistry(apple);
  }

  @Inject
  AppleRegistry(
    Provider<GoodApple> goodAppleProvider,
    Provider<BadApple> badAppleProvider,
    Provider<BrandedApple> brandedAppleProvider
    SystemHelper systemHelper) {
      this(systemHelper, goodAppleProvider.get(), badAppleProvider.get(), brandedAppleProvider.get());
    }
  
  private static ImmutableMap<String, Apple> createRegistry(Apple... apple){......}
  
  public Apple findApple(String key) {....}
}

// This is an existing class
@Singleton
public class SystemHelper {
  private final SystemDao systemDao;

  @inject
  public SystemHelper(SystemDao systemDao) {
    this.systemDao = systemDao;
  }
....
}

public class SystemDao {
  private final SpannerProtoDao<SystemConfig> spannerProtoDao;

  @Inject
  public SystemDao(@AbcDatabase Database abcDatabase) {
    spannerProtoDao = SpannerProtoDao.newBuilder(SystemConfig.class)
                         .setDatabase(abcDatabase)
                         .setTable("Table").setMessageColumn("column")
                         .build();
  }
}
 

Теперь, когда я пишу тест для новых изменений, время ожидания истекает
Тестовый код:

 @RunWith(JUnit4.class)
@SmallTest
public class AppleRegistryTest {

  private final SystemHelper systemHelper;

  @Before
  public void setUp() throws Exception {
    Guice.createInjector((Module) new SystemHelper(new SystemDao(TestUtil.createDatabase()))).injectMemeber(this);
  }

  @Test
  public void testFindApple_emptyRegistry() {
    Optional<Apple> apple = new AppleRegistry(systemHelper).findApple("First");
    assertFalse(apple.isPresent());
  }
}
 

Может кто-нибудь, пожалуйста, помочь мне в написании тестового класса для AppleRegistry.
Заранее спасибо!

Ответ №1:

Я сделал что-то вроде этого. Это плохая практика кодирования?

 public class AppleRegistryTest {
  @Rule public final Mocks mocks = new Mocks(this);
  @Mock private SystemHelper systemHelper;

  @Test
  public void testFindApple_emptyRegistry() {
    Mockito.when(systemHelper.isXyzEnabled()).thenReturn(False);
    Apple apple = new AppleRegistry(systemHelper).findApple("First");
    assertFalse(apple.isPresent()); 
  }
}