Java @InjectMocks后为Null

Java @InjectMocks后为Null,java,null,mocking,mockito,inject,Java,Null,Mocking,Mockito,Inject,在使用JUnit进行单元测试时,我在传递依赖项时遇到了一些问题 考虑以下几段代码: 这是我要测试的类的依赖注入,我们称它为控制器 @Inject private FastPowering fastPowering; 这是单元测试: @RunWith(MockitoJUnitRunner.class) public class ControllerTest { @Mock FastPowering fastPower; @InjectMocks Controller controller

在使用JUnit进行单元测试时,我在传递依赖项时遇到了一些问题

考虑以下几段代码:

这是我要测试的类的依赖注入,我们称它为控制器

@Inject private FastPowering fastPowering;  
这是单元测试:

@RunWith(MockitoJUnitRunner.class)
public class ControllerTest {

@Mock
FastPowering fastPower;

@InjectMocks
Controller controller;

@Test
public void test() {
    assertEquals(
            (controller.computeAnswer(new BigDecimal(2), 2)).longValue(),
            (long) Math.pow(2, 2));
    }
}
fastPower似乎为空,请解释如何修复该问题。 空指针异常,因为在.computeAnswer方法中调用@injected字段(fastPower)

编辑:


我应该读一下@Mock和@Spy之间的区别

由于有很多评论,我正在为解决方案添加更多的上下文

不同之处在于,在mock中,您创建的是一个完整的mock或伪对象,而在spy中,存在真实的对象,您只需对其特定方法进行监视或存根。当然,在spy对象中,由于它是一个真实的方法,当您不存根该方法时,它将调用真实的方法行为

如果fastPower被注释为@Mock,那么它的方法是虚拟的,然而controller.computeAnswer依赖于它们进行计算。一个人必须提供行为

如果使用spy时没有存根,那么将执行fastPower的真正实现,最终返回所需的值

另一种选择是使用真正的FastPowering实例

还有一些stackoverflow线程概述了差异


简短回答:将
@Mock
替换为
@Spy
,应该可以正常工作使用
MockitoAnnotations.initMocks
启动
@Mock
@InjectMocks
对象。您的测试看起来像:

@Mock
FastPowering fastPower;

@InjectMocks
Controller controller;

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
}

@Test
public void test() {
    ....
}

还有两件事需要检查:

1. Mocking the behaviours of fastPower. What should this mocked object return, when it methods are called? i.e. when(fastPower.doSomething()).thenReturn(some_kind_of_object);
2. Check if the controller.computeAnswer() does not return NULL for the input of new BigDecimal(2), 2)).longValue(), (long) Math.pow(2, 2).

调试之后,我找到了一个原因。这是因为集合
org.powermock.core.MockRepository#instanceMocks
不包含带有
@InjectMocks
注释的字段的模拟(
Controller
)。 要解决此问题,请尝试在字段声明中使用
@Spy
注释并初始化它们,以及在类声明上方使用
@PrepareForTest

@PrepareForTest(Controller.class)
@RunWith(MockitoJUnitRunner.class)
公共类控制器测试{
@嘲弄
快速动力快速动力;
@间谍
@注射模拟
控制器=新控制器();
@试验
公开无效测试(){
//...
}
}

对我来说,这很有帮助。使用方法
Mockitoannotations.initMocks(this)
不是必需的,它不会影响结果。

需要注意的是使用
Mockitoannotations.initMocks(this)
需要在
/
setUp()
方法之前的
@的末尾出现

如果它位于
setUp()
的顶部,则可能会导致其他模拟类无法初始化


我自己刚才遇到了这个错误,并将
.initMocks
放在
@的末尾,然后
解决了我的问题。

我通过删除@Before方法中创建的无关新实例(参见下面的示例)修复了这个问题。通过移动
MockitoAnnotations.initMocks(this)
在初始化
myClass
之后,它也被修复了,但是由于Mockito创建了
myClass
,所以这个解决方案就差了

// Note - you may need @mock(name="foo") to help mockito differentiate props
//        if they have the same type
@mock
private Thing something;

@InjectMocks
private MyClass myClass;

@Before
 public void setUp() {
    MockitoAnnotations.initMocks(this); // Moving this below the next line fixed it...
    myClass = new MyClass() // But just remove this line and let Mockito do the work
}

你的错误是什么?此外,computeAnswer中的代码是什么?空指针异常,computeAnswer使用fastPower中的方法来计算^power的值,这就是为什么在调用静态或最终方法时,它使用空指针失败的原因?@rpet您找到解决方案了吗?“解决了我应该阅读@Mock和@Spy之间的区别…”是否可以发布并接受您的解决方案作为答案?这可能会帮助其他用户解决同样的问题并关闭此线程。同样的问题,@InjectMocks和MockitoAnotations之后的NPE。initMocks(this)@VB_u您是否能够解决此问题?如果是,如何进行?