簡體   English   中英

Java:將帶有Inject注釋的類添加為Junit

[英]Java: Junit a class with Inject annotation

@Singleton
public class RealWorkWindow implements WorkWindow {

    @Inject private Factory myFactory;

    public RealWorkWindow (
            LongSupplier longSupplier
    ) {
        defaultWindow = myFactory.create(() -> 1000L);
        workWindow = myFactory.create(longSupplier);
    } 
    ...

如您所見,我正在注入工廠類(通過FactoryModuleBuilder注入)

測試碼

@Test
public class RealWorkWindowTest {
    private RealWorkWindow testWindow;

    @BeforeMethod
    void setup() {
        MockitoAnnotations.initMocks(this);

        testWindow = spy(new RealWorkWindow(() -> 1L));
    }

Factory.py

public interface RealWorkWindowFactory {
    RealWorkWindowFactory create(LongSupplier longSupplier);
}

install(new FactoryModuleBuilder()
                        .implement(WorkWindow.class, RealWorkWindow.class)
                        .build(RealWorkWindowFactory.class));

當我運行RealWorkWindowTest測試時,NPE測試失敗,表明工廠不存在,這是有道理的,因為我認為注入不會運行。

如何在junit中使用Injection進行測試? 或嘲笑嗎?

https://mhaligowski.github.io/blog/2014/05/30/mockito-with-both-constructor-and-field-injection.html中描述的問題類似

但是我的問題是在IN構造函數中使用了模擬,因此在實例化測試對象時它仍然為null(因為我尚未調用Mockito.init)

如果使用MockitoJUnitRunner ,則可以使用@Mock為Factory創建一個模擬並注入它。

@RunWith(MockitoJUnitRunner.class)
public class MyTest {

    @Mock
    private Factory myFactory;

    @InjectMocks
    private RealWorkWindow realWorkWindow;

    @Test
    public void testSomething() {
        when(myFactory.create(/* insert param here */)).thenReturn(/* insert return value here */);

        /* perform your test */
    }
}

使用@Assisted注入時使用構造@Assisted注入

Guice的Assisted Injection Wiki頁面提到:

AssistedInject自動生成工廠類的實現。 要使用它,請注釋實現類的構造函數和注入器不知道的字段:

然后:

AssistedInject將create()方法的參數映射到實現類的構造函數中的相應@Assisted參數。 對於其他構造函數參數,它要求常規的Injector提供值。

由於它們僅在那時可用,因此Guice將僅在構造函數調用之后注入字段。 這意味着您必須使用構造函數注入 ,而不要使用其他機制(除非您具有允許@PostConstruct或類似的擴展名)。

因此,讓我們根據此代碼進行重寫。 編寫您的RealWorkWindow ,如下所示:

@Singleton
public class RealWorkWindow implements WorkWindow {

  private final WorkWindow defaultWindow;
  private final WorkWindow workWindow;

  @Inject
  public RealWorkWindow(Factory myFactory, @Assisted LongSupplier longSupplier) {
    defaultWindow = myFactory.create(() -> 1000L);
    workWindow = myFactory.create(longSupplier);
  }

}

然后,您的代碼可以變得可測試,如下所示:

@RunWith(MockitoJunitRunner.class)
public class RealWorkWindowTest {

  @Mock
  Factory myFactory;

  @Mock
  WorkWindow defaultWindow;

  @Mock
  WorkWindow workWindow;

  RealWorkWindow realWorkWindow;

  @BeforeEach
  void setup() {
    when(myFactory.create(any(LongSupplier.class)))
        .thenReturn(defaultWindow) // First call
        .thenReturn(workWindow);   // Second call
    realWorkWindow = new RealWorkWindow(myFactory, () -> 1000L);
  }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM