我有一个我这样嘲笑的课:
@Mock
private MyClass1 mockMyClass1;
说这个类看起来像这样:
public class MyClass1 {
@Autowired
private MyInnerClass myInnerClass;
}
当我模仿MyClass1
时,MyInnerClass
将被初始化为null
。是否可以用另一个模拟对象来初始化该私有字段?我希望myInnerClass
像这样嘲笑:
@Mock
private MyInnerClass myInnerClass;
如果我使用以下代码:
@InjectMocks
private MyClass1 mockMyClass1;
@Mock
private MyInnerClass myInnerClass
这会将MyInnerClass
内的私有MyClass1
初始化为模拟对象,但这种方式mockMyClass1
不再是模拟本身,不是吗(我只是在真实类中注入一个模拟对象,就像@Autowired
会注入一个真实对象一样)?如果我对@InjectMock
和@Mock
的理解错了,你能纠正我的逻辑吗?我怎么能在另一个模拟对象中注入一个模拟对象(不使用setter / constructors)?
答案 0 :(得分:7)
你误解了mock是什么。
当您模拟MyClass1
时,模拟对象的类型MyInnerClass
的内部字段不再存在。因此,尝试向模拟中注入某些内容是没有意义的。
通过说明与它交互时它应该做什么来控制模拟。您将其公共方法存根以执行您希望它们执行的操作。你给出了行为。唯一的默认行为(可能特定于Mockito)是在没有配置模拟的情况下返回null
(但请注意它不会返回null
因为某个内部变量是null
},它返回,因为Mockito决定它应该返回;也许另一个模拟框架决定它应该抛出异常,谁知道?)。
举个例子,考虑一下你真正的班级是:
class MyClass1 {
private MyInnerClass myInnerClass;
public MyInnerClass getMyInnerClass() {
return myInnerClass;
}
}
现在考虑mock
模拟该类。如果您致电mock.getMyInnerClass()
,则 将是要调用的真实方法。它返回的是不 myInnerClass
的值。它将返回null
,或者如果您使用
when(mock.getMyInnerClass()).thenReturn(something);
然后它将返回something
。
所以回答你的问题:你不能这样做,因为这不是模拟的工作方式。
答案 1 :(得分:1)
您根本不应该使用InjectMocks注释(要了解原因,您可以阅读此article)。
您可以为MyClass1而不是Autowired字段实现Autowired构造函数。然后你可以简单地将MyInnerClass模拟引用作为构造函数参数传递。