当我使用 @InjectMocks
时,发生了异常。我的代码如下所示:
class A {
private X x;
private Y y;
public A(String ip, int port) {
this(someMethodCall(ip, port)); //
}
private A(X x) {
this.x = x;
this.y = new Y();
}
}
UT:
public class ATest() {
@InjectMocks A a;
@Mock X x;
@Mock Y y;
@Test ...
}
它会抛出 NPE,有人可以帮助我吗?
org.mockito.exceptions.base.MockitoException: Cannot instantiate @InjectMocks field named 'channel' of type 'class Juinit3.Channel'. You haven't provided the instance at field declaration so I tried to construct the instance. However, the constructor or the initialization block threw an exception: null.
原文由 dingrui 发布,翻译遵循 CC BY-SA 4.0 许可协议
这个异常告诉你什么……
换句话说,你没有写…
这是完全可以接受的,并且可能会解决您的问题。请记住,此时不会初始化模拟,因此如果您真的需要一个示例
String
和int
就可以了,但如果您需要将模拟放在那里则不需要。换句话说,如果您有一个采用 X 的构造函数,并且您将在此处编写新的A(x)
,则 x 将为空,因为@Mock
注释尚未处理。因为没有实例(因为你没有提供)它试图创建一个,但是……
所以,你的构造函数抛出 null。似乎你的
someMethodCall
依赖于参数(端口,最有可能)不为空,但因为它们是String
和int
to在那里使用什么值。由于port
是原始类型并且 Mockito 没有专门处理这些类型,问题可能就在那里 - Mockito 会尝试将 null 放在那里,这将引发异常。例如,如果您的构造函数匹配 X 和 Y,Mockito 可能会尝试将模拟放在那里,但事实并非如此。构造函数想要
String
和int
并且没有针对它们的模拟,因此 Mockito 只能使用默认值,这些是null
中的问题,这是一个问题port
(因为int
)。那么,解决方案是什么?
1)要么让你的构造函数空安全,允许在那里给一个空端口(并确保 ip 字符串也以空安全的方式处理)。
2)使用你没有使用的东西:
在任何情况下,都不需要在构造函数中拥有所有依赖项,Mockito 可以将它们直接注入到字段中。因此,为 X 和 Y 添加另一个构造函数并不是真正的解决方案。当然,一般来说,构造函数注入优于字段注入,但这是另一个话题。
至于你关于哪个构造函数的问题: 文档 说这个……
编辑: 似乎 Mockito 不知道如何处理构造函数中的原始字段,真可惜。