【发布时间】:2019-09-07 07:26:22
【问题描述】:
如果使用注释 @Mock 进行模拟,为什么模拟对象在测试类实例化后显示为“锁定”并且在 @Produced 方法中显示为 null
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);
}
}
有两件事让我感到困惑,我希望得到一些帮助来理解:
1) @Mock(带注释的字段)在 @Producer 方法中为空,但如果我使用 = Mockito.mock(xxx.class) 代替,则初始化。据我所知,这与何时执行符号与何时应用 @Rule 有关。更多细节将不胜感激......
2) 我非常希望能够让 mock 在不同的测试用例中做不同的事情,但这似乎是不可能的,因为当 mockito.when() 没有时 @Produces 方法“停留在过去”还没申请。我怎样才能“安排”公关。测试用例?拥有一个测试级公关。随着时间的推移,测试用例将变得无法维护......代码变得非常混乱。
编辑:我发现将我的模拟对象设为静态,可以设置我的模拟对象 pr。测试方法。我进行了调试运行,并注意到生产者返回的对象与 jUnit @Test 中使用的实例不同 - 显然 @Produces 在 MyTest 类的另一个实例上运行......对我来说仍然没有意义,还是这样:如果有人有一些知识,请分享。
【问题讨论】:
-
您打算编写IntegrationTest 还是UnitTest?其次,您根本不需要使用 CDI,可以直接提供模拟。 “卡在过去”背后的问题可能是焊缝可能会将模拟包装成代理。
-
我的意图是编写一个集成测试,但在 jUnit 设置中运行它以避免启动容器。我已经对帖子进行了更新。我做了一些调试,因为我记得你提到的关于代理的事情。
-
也许 cdi-unit 或 ioc-unit (github.com/1and1/ioc-unit/tree/master/ioc-unit-mockseasy) 对您的情况有所帮助。要使“@Mock”有效,Mockito 必须了解该类。要使“@Inject”生效,如果“@InjectMocks”不够,则必须运行 CDI。