我有类似
的东西private static final CustomObject ObjectA = new CustomObject();
@Mock
Foo1 foo1;
@Mock
Foo2 Foo2 = new Foo2(ObjectA);
@Mock
Foo3 foo3;
@InjectMocks
ContainerClass container;
我想在将objecta注入容器中之前用objecta初始化foo2。以上代码不起作用。
编辑:我正在尝试模拟foo2,但是有一个内部对象foo2我想用真实对象初始化,因此当我调用foo2的方法时,将使用此内部对象来为我提供基于我需要的结果我在构造过程中提供的值。
上述代码不起作用。
1(@InjectMocks
使用了很多"魔术",不是必需的最清晰和可疑的方法来设置正在测试的对象的模拟。
在引擎盖下,它尝试了多件事:构造仪注入,房地产设置器注入,现场注射。
但是,如果它无法注入,则不会报告失败:
如果以下任何策略失败,那么摩擦图就不会报告 失败;即您必须自己提供依赖项。
作为替代方案,您可以明确设置正在测试的对象的依赖项。
2(侧面,但要注意:用小写为第一个字母将变量命名。用班级名称命名不可读取和常规。
3(这是没有意义的:
@Mock
Foo2 Foo2 = new Foo2(ObjectA);
您实例化 Foo2
,然后用overito模拟代替。
嘲笑Foo2
行为,但让其ObjectA
依赖性为"无模拟对象"不是真正的逻辑。
通过这样做,您不会真正嘲笑正在测试的对象的依赖项,因为您的调用模式是:
测试的对象 ->模拟dep1->真实对象dep2
在这种情况下,编写集成测试(无模拟(是更有意义的。
在单位测试ContainerClass
时,您将仅测试ContainerClass
行为。
您想要获得结果的ObjectA
方法应该是Foo2
呼叫ObjectA
,您可以在测试中模拟Foo2
的调用。
请注意,如果您模拟其呼叫者的方法,则不需要模拟ObjectA
。
这是一个示例:
public class Foo2{
private ObjectA objectA;
public Foo2(ObjectA objectA){
this.objectA = objectA;
}
public Bar callObjectA(){
return objectA.foo();
}
}
您需要在这里模拟的是callToObjectA()
。
@Mock
Foo1 foo1;
@Mock
Foo2 foo2;
@Test
public void myMethod(){
ContainerClass container = new ContainerClass(foo1, foo2);
Bar mockedBar = new Bar(....);
Mockito.when(foo2.callObjectA()).thenReturn(mockedBar);
// invoke the method under test
container.myMethod();
// assertions ...
}
代码样式,您遇到的问题是Foo2
并不是真正的模拟,因为您明确对其进行实例化。如果您确实想使用与Object2
实例实例化的"真实" Foo2
实例,请考虑在Foo2
上使用@Spy
注释。然后,@InjectMocks
注释应执行您的期望。