mock instance is null after @Mock annotation

我试着做这个测试:

    @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.

我错过了什么?

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

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

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {


@Mock
private IRoutingObjHttpClient routingClientMock;


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


}

See also 本教程.

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

Use the 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 {
// ...
}
}

如果您也在使用 PowerMock,那么

@RunWith(MockitoJUnitRunner.class)

可以被

@RunWith(PowerMockRunner.class)

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

尝试检查您正在调用的方法是否是 期末考试方法。

Mockito 不能模仿最终的方法

它也可能是一个导入问题,所以请确保您有适当的导入包。

例如,“ org.easymock”包也有一个名为@Mock 的注释,当然,这个注释不能用于特定于 Mockito 的设置。

If you use junit.jupiter with @ExtendWith(MockitoExtension.class) for test class but 模拟是无效的, ensure that @Test annotation is imported from

import org.junit.jupiter.api.Test;

instead of org.junit.Test;

Same problem can occur if you are using Junit5 since there is no more '@RunWith' annotation.

在这种情况下,您应该用以下方式注释您的类:

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

You should also import into your dependency (Maven - pom.xml):

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

For me, even after adding @RunWith(MockitoJUnitRunner.class) it was not working.
原来,我犯了一个愚蠢的错误,把 @Test

import org.junit.jupiter.api.Test;

而不是

import org.junit.Test;

修正之后,它起作用了!

对于我添加到类的注释:

@RunWith(MockitoJUnitRunner.class)

并修改了 Mockito 的版本,解决了这个问题。

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

是什么为我解决了这个问题(结合上面的答案和我自己的补充) :

  • MockitoAnnotations.initMocks(this); in the @Before method
  • 测试类必须是公共的
  • 测试方法必须是公共的
  • import org.junit.Test;而不是 import org.junit.jupiter.api.Test;

在 Intellij 执行 command + N-> Test...时,它会生成(至少作为默认值)一些在我的例子中不起作用的样板文件。

我也有同样的问题,但是我发现将我的测试(最初是为 JUnit 3编写的,并使用了遗留的 setUp()tearDown()方法)更新为 JUnit 4,并且现代的带注释的 fixture 方法是有效的。

Additionally, if you're using the Rule:

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

确保这个规则也在一个公共类中,否则你会收到这样的信息:

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

对我来说,当我加上:

  1. 班级层面:
@RunWith(MockitoJUnitRunner.class).
  1. 课内活动:
@Before
public void createMocks() {
MockitoAnnotations.initMocks(this);
}

@ ExtendWith (MockitoExtension.class)注释添加到测试类中,它应该可以工作,因为您使用的是 Junit5 + 版本。 如果您使用的是旧版本的 Junit,请使用 @ RunWith (MockitoJUnitRunner.class)注释。

我遇到了这样的问题: 我声明了@Mock MyClass myClass,然后试图在我的@Before All 注释方法中模仿一个行为:

@Mock
private MyClass myClass;


...


@BeforeAll
public void init()
{
...
Mockito.when(myClass.something()).thenReturn("Not found")
...
}

很明显,init ()是在模拟初始化 myClass 之前执行的,所以在 init ()中 myClass = = null。

解决方案是将注释从@BeforeAll 更改为@Beforeeach。

在对我有效的评论中找到了这个解决方案。对正在创建的所有模拟执行这个操作。

您需要实例化路由 ClientMock。

routingClientMock = Mockito.mock(RoutingObjHtttpClient.class);

My issue was that I was trying to mock an object which was final in my service. Just needed to remove final and it worked.

使用 InjectMocks 的 Junit 5

 @ExtendWith(MockitoExtension.class)
public class MyClientTest {
@Mock
Environment environment;
@Mock
ClassCreator classCreator;


@InjectMocks
MyClient myClient;




@Test
public void mytest() {
myClient = new MyClient(environment, classCreator);
            

}
}