[英]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進行測試? 或嘲笑嗎?
但是我的問題是在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.