[英]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.