gpt4 book ai didi

java - @InjectMocks,构造函数或初始化 block 抛出异常

转载 作者:行者123 更新时间:2023-12-02 08:37:53 28 4
gpt4 key购买 nike

当我使用@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:无法实例化名为“class Juinit3.Channel”类型的“channel”的 @InjectMocks 字段。您尚未在字段声明中提供实例,因此我尝试构造该实例。但是,构造函数或初始化 block 抛出异常:null。

最佳答案

这个异常告诉你什么......

You haven't provided the instance at field declaration

换句话说,你没有写...

@InjectMocks 
A a = new A("foobar", 123);

这是完全可以接受的,并且可能会解决您的问题。请记住,此时模拟不会被初始化,因此如果您确实需要那里的示例 Stringint 也没有问题,但如果您需要在那里放置模拟则不然。换句话说,如果您有一个带有 X 的构造函数,并且您将在此处编写 new A(x),则 x 将为 null,因为 @Mock 注释不会尚未处理。

so I tried to construct the instance

因为没有实例(因为您没有提供实例),所以它尝试创建一个实例,但是...

However, the constructor or the initialization block threw an exception: null

所以,你的构造函数抛出 null。似乎您的 someMethodCall 依赖于参数(端口,最有可能)不为空,但由于它们是 Stringint,Mockito不知道在那里使用什么值。由于 port 是一个原始类型,并且 Mockito 不专门处理这些类型,因此问题可能就在那里 - Mockito 会尝试将 null 放在那里,这将引发异常。

例如,如果您的构造函数匹配 X 和 Y,Mockito 可能会尝试将模拟放在那里,但事实并非如此。构造函数需要 Stringint 并且没有它们的模拟,因此 Mockito 只能使用默认值,并且这些值是 null,这是一个port 出现问题(因为 int)。

那么,解决方案是什么?

1) 要么让你的构造函数空安全,允许在那里给出空端口(并确保 ip 字符串也以空安全方式处理)。

2)使用你没有使用过的东西:

@InjectMocks 
A a = new A("foobar", 123);

无论如何,构造函数中不需要包含所有依赖项,Mockito 可以直接将它们注入(inject)到字段中。因此,为 X 和 Y 添加另一个构造函数并不是真正的解决方案。当然,一般来说,构造函数注入(inject)比字段注入(inject)更可取,但那是另一个话题了。

至于你关于哪个构造函数的问题: documentation说这个...

the biggest constructor is chosen, then arguments are resolved with mocks declared in the test only

编辑:似乎 Mockito 不知道如何处理构造函数中的原始字段,真是可惜。

关于java - @InjectMocks,构造函数或初始化 block 抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47465594/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com