在使用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似乎为空,请解释如何修复. Null指针异常,因为在.computeAnswer方法中调用@injected字段(fastPower))
编辑:
解决了我应该读到@Mock和@Spy之间的区别...
由于有很多评论,我将为解决方案添加更多上下文
不同的是,在mock中,你创建的是一个完整的mock或fake对象,而在spy中,有一个真正的对象,你只是窥探或存根它的特定方法。而在spy对象中,当然,由于它是一个真正的方法,当你不存根该方法时,它将调用真正的方法行为。
如果fastPower被标注为 @Mock,它的方法是虚拟的,但是 controller.computeAnswer 依赖于它们来计算。必须提供行为。
如果使用spy而不使用存根,则会执行 fastPower 的实际实现,最终返回所需的值。
另一种选择是使用真实的 FastPowering 示例
https://github.com/mockito/mockito/wiki/Using-Spies-(and-Fakes)https://github.com/mockito/mockito/wiki/Mocking-Object-Creation显示器
一些堆栈溢出线程概述了Mocking vs. Spying in mocking frameworks的不同之处。
简短回答:将@Mock
替换为@Spy
,应该可以正常工作
6条答案
按热度按时间a11xaf1n1#
使用
MockitoAnnotations.initMocks
来初始化@Mock
和@InjectMocks
对象。您的测试看起来会像这样:omtl5h9j2#
我通过删除我在@Before方法中创建的无关的新示例(见下面的示例)修复了这个问题,也通过在初始化
myClass
后移动MockitoAnnotations.initMocks(this)
修复了这个问题,但由于Mockito还是创建了myClass
,所以这个解决方案是次优的。h7wcgrx33#
调试后我发现了一个原因。这是因为集合
org.powermock.core.MockRepository#instanceMocks
不包含一个带有@InjectMocks
注解的字段的mock(在您的例子中是Controller controller
)。要解决这个问题,请尝试在字段声明中使用@Spy
注解,初始化它们,并在类声明上方使用@PrepareForTest
:在我的例子中,它有帮助。使用方法
Mockitoannotations.initMocks(this)
不是必需的,它不会影响结果。llew8vvj4#
需要注意的是,
MockitoAnnotations.initMocks(this);
的使用需要在@Before
/setUp()
方法的结尾出现。如果它在
setUp()
的顶部,那么它可能会导致其他模拟类无法初始化。我刚才自己也遇到了这个错误,把
.initMocks
放在我的@Before
的末尾解决了我的问题。qncylg1j5#
我使用了错误的
@Test
注解,如果您想在Mockito测试中使用@InjectMocks
和@Mock
,那么您应该1.在测试类上添加
@ExtendWith(MockitoExtension.class)
注解1.使用
@Test (org.junit.jupiter.api.Test)
而不是@Test (org.junit.Test)
注解来注解您的测试方法。请小心使用您用于此注解的导入。这适用于
mockito-core:3.6.28
guicsvcw6#
还有两件事要检查: