@InjectMocks,构造函数或初始化块引发异常 [英] @InjectMocks, the constructor or the initialization block threw an exception

查看:935
本文介绍了@InjectMocks,构造函数或初始化块引发异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用@InjectMocks时,发生了异常.我的代码如下所示:

When I use @InjectMocks, an exception was occurred. My code is shown below:

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,有人可以帮助我吗?

it will throw an NPE, can someone help me?

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.

推荐答案

这种观念告诉你的东西...

What this exeception is telling you...

您尚未在字段声明中提供实例

You haven't provided the instance at field declaration

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

In other words, you did not write...

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

这将是完全可以接受的,并且可能会解决您的问题.请记住,此时不会对模拟进行初始化,因此如果您确实需要在其中放置示例Stringint,则很好,但是如果您需要在此处放置模拟,则可以.换句话说,如果您有一个使用X的构造函数,并且您将在此处编写新的A(x),则x将为null,因为尚未处理@Mock批注.

This would be completely acceptable and will probably solve your problem. Please remember that mocks will NOT be initialized at that point, so it's fine if you really need an example String and int there, but not if you need to put mocks there. In other words, if you had a constructor that took an X and you would write new A(x) here, x would be null, since the @Mock annotation would not have been processed yet.

所以我试图构造实例

so I tried to construct the instance

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

Because there was no instance (because you didn't provide one) it tried to create one, but...

但是,构造函数或初始化块引发了一个异常:null

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

因此,您的构造函数将引发null.好像您的someMethodCall依赖于给定的参数(端口,最有可能不是空值),但是由于它们是Stringint,因此Mockito不知道在那里要使用什么值.由于port是原始类型,而Mockito并未专门处理这些类型,因此问题可能出在这里-Mockito会尝试在其中放置null,这将引发异常.

So, your constructor throws null. Seems like your someMethodCall relies on the arguments (port, most likely) given not to be null, but since they are String and int, Mockito has no idea what values to use there. Since port is a primitive type and Mockito does not handle those specifically, the problem is probably there - Mockito will try to put null there, which will throw an exception.

例如,如果您的构造函数匹配X和Y,则Mockito可能会尝试将模拟放置在此处,但事实并非如此.构造函数需要Stringint,并且没有模拟,因此Mockito只能使用默认值,而默认值是null,这对于port来说是个问题(由于int).

If your constructor matched X and Y, for example, Mockito would probably try to put the mocks there, but it doesn't. The constructor wants String and int and there are no mocks for them, so Mockito can only use default values and those are null, which is a problem in case of port (because of int).

那么,解决方案是什么?

So, what's the solution?

1)要么使构造函数为null安全的,然后允许在其中提供null端口(并确保ip字符串也以null安全的方式进行处理).

1) Either make your constructor null-safe, allowing to give a null-port there (and make sure that the ip string is also handled in a null-safe way).

2)使用您不使用的东西:

2) Use the thing you didn't use:

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

在任何情况下,都不需要在构造函数中包含所有依赖关系,Mockito会很好地将它们直接注入字段中.因此,为X和Y添加另一个构造函数不是真正的解决方案.当然,通常,构造函数注入优于字段注入,但这是另一个主题.

In any case, it is not required to have all the depedencies in the constructor, Mockito will do fine injecting them into fields directly. So adding another constructor for X and Y is not a real solution. Of course, generally, constructor injection is preferable over field injection, but that's another topic.

关于您有关哪个构造函数的问题:

As for your question about which constructor: The documentation says this...

选择最大的构造函数,然后仅使用在测试中声明的模拟来解析参数

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

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

Seems that Mockito does not know how to handle primitive fields in constructors, what a shame.

这篇关于@InjectMocks,构造函数或初始化块引发异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆