@Mock注释后,模拟实例为null


74

我尝试运行此测试:

    @Mock IRoutingObjHttpClient routingClientMock;
    @Mock IRoutingResponseRepository routingResponseRepositoryMock;


    @Test
    public void testSendRoutingRequest() throws Exception {
        CompleteRoutingResponse completeRoutingResponse = new CompleteRoutingResponse();
        completeRoutingResponse.regression_latencyMillis = 500L;

        Mockito.when(routingClientMock.sendRoutingRequest(any(RoutingRequest.class))).thenReturn(completeRoutingResponse);

        RoutingObjHttpClientWithReRun routingObjHttpClientWithReRun = new RoutingObjHttpClientWithReRun
                (routingClientMock, routingResponseRepositoryMock);

...
    }

但我得到NullPointerException为:

Mockito.when(routingClientMock.

我想念什么?


8
你打MockitoAnnotations.initMocks(this)吗?(可能在@Before方法中)或者,您还有其他想要初始化模拟的@Rule吗?(这不是自动魔术)
安迪·特纳

您需要实例化routingClientMock例如routingClientMock = Mockito.mock(RoutingObjHtttpClient.class);
Tim Biegeleisen 2015年

您也可以@RunWith(MockitoJUnitRunner.class)在课堂上使用
Roland Weisleder 2015年

请写一个答案,我会做标记
Elad Benda2 2015年

Answers:


97

当您要使用@Mock注释时,应使用MockitoJUnitRunner

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {

    @Mock
    private IRoutingObjHttpClient routingClientMock;

    @Test
    public void testSendRoutingRequest() throws Exception {
        // ...
    }

}

另请参阅本教程


1
它对我不起作用总是给出此错误“ dexcache == null(并且找不到默认值;考虑设置'dexmaker.dexcache'系统属性)”
pyus13

@ pyus13这应该是一个包含更多代码的新问题。
罗兰·韦斯勒德

赞赏响应,我认为问题是我在JUnit Test中使用了它,而当一些代码合并了团队中的某个人时,错误地添加了dex maker testImplementation依赖项。从build.gradle中删除该行后,一切开始工作。希望能节省一些人的时间。
pyus13

通过使用@Mock注释,这会使构建失败。
大卫,

@David我认为您的问题应该是一个带有完整示例的新问题。
罗兰·韦斯勒德

57

您可以使用三个选项来激活@Mock注释:MockitoRule,MockitoJUnitRunner,MockitoAnnotations.initMocks(this)。恕我直言,使用MockitoRule最好的一种,因为它仍然可以让您选择另一个跑步者,例如Parameterized

使用MockitoRule

public class MockitoTest {

  @Mock
  private IRoutingObjHttpClient routingClientMock;

  @Rule
  public MockitoRule rule = MockitoJUnit.rule();

  @Test
  public void testSendRoutingRequest() throws Exception {
    // ...
  }
}

使用MockitoJUnitRunner

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {

  @Mock
  private IRoutingObjHttpClient routingClientMock;

  @Test
  public void testSendRoutingRequest() throws Exception {
    // ...
  }
}

显式调用MockitoAnnotations.initMocks(this)

可以使用qn@Before方法,您自己的运行器或自己的规则来完成。

public class MockitoTest {

  @Mock
  private IRoutingObjHttpClient routingClientMock;

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

  @Test
  public void testSendRoutingRequest() throws Exception {
    // ...
  }
}

在大多数测试类中,@ RunWith(MockitoJUnitRunner.class)可以很好地注入模拟。但是在少数测试类中,@ RunWith(MockitoJUnitRunner.class)和MockitoAnnotations.initMocks(this)只能一起使用。这个问题有什么解释吗?
Nakul Goyal

您能否用一个完整的例子在StackOverflow上创建另一个问题。
Stefan Birkner

17

如果您使用的是Junit5,可能会出现相同的问题,因为没有更多的'@RunWith'注释。

在这种情况下,您应该使用以下注释您的班级:

@ExtendWith(MockitoExtension.class)
public class MyTestClass {
...

您还应该导入依赖项(Maven-pom.xml):

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>${mockito.version}</version>
    <scope>test</scope>
</dependency>

对于当今大多数阅读此主题的人来说,这很可能是正确的解决方案。
Rouven H.

这个答案从字面上拯救了我的命,应该在所有答案+1的最上方列出它。
Tim Biegeleisen

14

如果将junit.jupiterwith@ExtendWith(MockitoExtension.class)用于测试类,但模拟为null,请确保@Test从中导入注释

import org.junit.jupiter.api.Test;

代替 org.junit.Test;


4

这也可能是导入问题,因此请确保您具有适当的导入包。

例如,“ org.easymock”软件包也确实有一个名为@Mock的注释,该注释当然不适用于特定于Mockito的设置。


4

对我来说,即使添加后@RunWith(MockitoJUnitRunner.class)也无法正常工作。
原来,我犯了一个愚蠢的错误,就是@Test

import org.junit.jupiter.api.Test;

代替

import org.junit.Test;

更正后,它起作用了!


2
  1. 你应该@RunWith(SpringJUnit4ClassRunner.class)在课堂上使用
  2. 您必须调用MockitoAnnotations.initMocks(this);@Before方法

2
为什么@RunWith(SpringJUnit4ClassRunner.class)和不MockitoJUnitRunner.class
Elad Benda2 2015年

您不需要SpringJUnit4ClassRunner,除非您想将某些Spring上下文连接到您的测试中-这是一个非常复杂的过程。
大卫·维克多


1

是什么为我解决了这个问题(上述答案和我自己添加的内容的结合):

  • MockitoAnnotations.initMocks(this); 在里面 @Before方法中
  • 测试班必须公开
  • 测试方法必须公开
  • import org.junit.Test; 代替 import org.junit.jupiter.api.Test;

Test...在Intellij中执行命令+ N->时,它会生成(至少默认情况下)至少在我的情况下不起作用的样板。


非常感谢你救了我。我的问题是您评论的最后一个。非常喜欢!
CodeMonkey

0

对我来说,将注释添加到类中:

@RunWith(MockitoJUnitRunner.class)

并修改Mockito的版本即可解决此问题。

<dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>2.23.4</version>
        <scope>test</scope>
</dependency>

0

我遇到了同样的问题,但是我发现更新了我的测试(该测试最初是为JUnit 3编写的,并且使用了旧版setUp()tearDown()方法)更新为JUnit 4,并且现代的带注释的夹具方法也可以使用。

此外,如果您使用规则:

@Rule public MockitoRule rule = MockitoJUnit.rule();

确保规则也属于公共课程,否则您将收到以下消息:

How did getFields return a field we couldn't access?

-4

如果您还使用PowerMock,则

@RunWith(MockitoJUnitRunner.class)

可以替换为

@RunWith(PowerMockRunner.class)

这将激活您@Mocks的功能并启用PowerMock功能。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.