Java Junit 4@Mock在@products方法中的作用域
如果使用注释@Mock进行模拟,为什么模拟对象在测试类安装后显示为“锁定”,在@producted方法中显示为nullJava Junit 4@Mock在@products方法中的作用域,java,mockito,junit4,weld,Java,Mockito,Junit4,Weld,如果使用注释@Mock进行模拟,为什么模拟对象在测试类安装后显示为“锁定”,在@producted方法中显示为null public class MyTest { @Rule public MockitoRule rule = MockitoJUnit.rule(); @Rule public WeldInitiator weld = WeldInitiator.from(MyTest.class).build(); //@Mock <-- this w
public class MyTest {
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Rule
public WeldInitiator weld = WeldInitiator.from(MyTest.class).build();
//@Mock <-- this wont work. Will be null in the @Produces methods
private ClassThatSutInjects sutInject= mock(ClassThatSutInjects.class);
private NeedsTest sut;
@Before
public void setup() {
sut = weld.select(NeedsTest.class).get();
}
@Test
public void doesThisWork() {
//Arrange
//Mockito.when(sutInject.multiply(anyInt()))
// .thenReturn(3);//this has no effect on the mock returned by @Produces
//Act
sut.doThis(1234);
//Assert
}
@Produces
public ClassThatSutInjects mockThatClass() {
Mockito.when(sutInject.multiply(anyInt())).thenReturn(100); //<-- this works
return sutInject;
}
}
public class NeedsTest {
@Inject
ClassThatSutInjects someClass
public void doThis(int number) {
return someClass.multiply(number);
}
}
公共类MyTest{
@统治
public MockitoRule rule=MockitoJUnit.rule();
@统治
public-WeldInitiator-weld=WeldInitiator.from(MyTest.class).build();
//@Mock正如您已经观察到的,生产者在对象的不同实例上运行
(第8.1章生产者方法的范围):
生产者方法不继承声明该方法的bean的作用域。这里有两个不同的bean:生产者方法和声明该方法的bean。生产者方法的作用域决定调用该方法的频率以及该方法返回的对象的生命周期。生产者方法的作用域声明生产者方法的方法确定调用生产者方法的对象的生命周期
使字段保持静态可以解决这个问题,但这并不是一个很好的解决方案。正如您已经观察到的那样,生成器在对象的不同实例上运行
(第8.1章生产者方法的范围):
生产者方法不继承声明该方法的bean的作用域。这里有两个不同的bean:生产者方法和声明该方法的bean。生产者方法的作用域决定调用该方法的频率以及该方法返回的对象的生命周期。生产者方法的作用域声明生产者方法的方法确定调用生产者方法的对象的生命周期
使字段静态化可以解决这一问题,但这并不是一个好的解决方案。您打算编写IntegrationTest还是UnitTest?第二,您根本不需要使用CDI,只需直接提供模拟。问题在于“停留在过去”可能是weld可能会将模拟封装到代理中。我的目的是编写一个integrationtest,但在jUnit设置中运行它,以避免使容器旋转。我已经对帖子进行了更新。我进行了一些调试,因为我记得您提到的关于代理的事情。也许cdi单元或ioc单元()对您的情况会有所帮助。对于“@Mock”要有效,Mockito必须了解类。要使“@InjectMocks”有效,如果“@InjectMocks”不够,则必须运行CDI。您打算编写IntegrationTest还是UnitTest?第二,您根本不需要使用CDI,只需直接提供mocks。“InjectMocks”背后的问题停留在过去“可能是weld可能会将模拟封装到代理中。我的意图是编写一个integrationtest,但在jUnit设置中运行它以避免容器旋转。我已经对帖子进行了更新。我进行了一些调试,因为我记得您提到的关于代理的事情。可能是cdi单元或ioc单元()可能对您的情况有所帮助。要使“@Mock”有效,Mockito必须了解类。要使“@InjectMocks”有效,如果“@InjectMocks”不够,则必须运行CDI。我同意静态不好(从来都不是这样)。如果您对其他解决方案有任何建议,我们将不胜感激。我想也许可以将制作人转移到一个单独的班级,并通过Weld访问它,以编辑“测试行为”为什么在集成测试中需要CDI
?可以选择在注入某些类后用mock替换它们,但是您也可以不使用CDI
,直接设置对象,您的旋转容器
做什么,您不想手动执行?另一个选项可能是不是注入模拟,而是注入存根
,允许您通过setter方法定义它们的行为(然后可以在其中设置模拟)。这将要求您使用并要替换的每个注入类都有一个适当的接口。我在集成测试中需要CDI的原因是,测试中的类使用注入:)我所说的不是“旋转容器”基本上,我不想让我的测试依赖于外部服务的答案。我不想模拟我的外部依赖,它们是通过注入提供的。我同意静态不好(从来都不是这样)。如果您对其他解决方案有任何建议,我们将不胜感激。我想也许可以将制作人转移到一个单独的班级,并通过Weld访问它,以编辑“测试行为”为什么在集成测试中需要CDI
?可以选择在注入某些类后用mock替换它们,但是您也可以不使用CDI
,直接设置对象,您的旋转容器
做什么,您不想手动执行?另一个选项可能是不是注入模拟,而是注入存根
,允许您通过setter方法定义它们的行为(然后可以在其中设置模拟)。这将要求您使用并要替换的每个注入类都有一个适当的接口。我在集成测试中需要CDI的原因是,测试中的类使用注入:)我所说的不是“旋转容器”基本上我不想让我的测试依赖于外部服务的答案,我不想模拟我的外部依赖,它们是通过注入提供的。