模拟实例在@Mock注释后为空



我尝试运行此测试:

    @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);
...
    }

但我得到空指针异常:

Mockito.when(routingClientMock.

我错过了什么?

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

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {
    @Mock
    private IRoutingObjHttpClient routingClientMock;
    @Test
    public void testSendRoutingRequest() throws Exception {
        // ...
    }
}

另请参阅本教程。

如果您使用的是 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>

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

使用模拟规则

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

如果将junit.jupiter与测试类的@ExtendWith(MockitoExtension.class)一起使用,但模拟为空,请确保从 导入@Test注释

import org.junit.jupiter.api.Test;

而不是org.junit.Test;

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

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

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

对我来说

,即使添加了@RunWith(MockitoJUnitRunner.class)它也无法正常工作。
事实证明,我犯了一个愚蠢的错误@Test

import org.junit.jupiter.api.Test;

而不是

import org.junit.Test;

纠正后,它奏效了!

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

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

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

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

我遇到了一个问题,我声明@Mock MyClass myClass,然后试图在我的@BeforeAll注释方法中模拟一种行为:

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

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

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

对我来说,当我添加:

  1. 在班级级别:
@RunWith(MockitoJUnitRunner.class).
  1. 课堂内:
@Before
      public void createMocks() {
        MockitoAnnotations.initMocks(this);
      }

尝试检查您调用的方法是否是最终方法。

Mockito不能模拟最终的方法。 https://github.com/mockito/mockito/wiki/FAQ

Junit 5 with InjectMocks。基于上述建议 https://stackoverflow.com/a/55616702/2643815

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

    @Test
    public void mytest() {
            myClient = new MyClient(environment, classCreator);
            
            }
            }
对我来说,将

注释添加到类中:

@RunWith(MockitoJUnitRunner.class)

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

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

我遇到了同样的问题,但我发现将我的测试(最初是为 JUnit 3 编写的,并使用传统的 setUp()tearDown()方法)更新到 JUnit 4 和现代注释夹具方法有效。

此外,如果您使用的是规则:

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

确保规则也在公共类上,否则您将收到以下消息:

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

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

您需要实例化 routetingClientMock,例如

routingClientMock = Mockito.mock(RoutingObjHtttpClient.class);
<</div> div class="one_answers">

我的问题是我试图模拟一个在我的服务中是最终的对象。只需要删除最终,它就起作用了。

我们的应用程序使用JUNIT5,发生了同样的问题。我用@InjectMocks替换了@Mock - 然后问题解决了

如果您也在使用 PowerMock,那么

@RunWith(MockitoJUnitRunner.class)

可以替换为

@RunWith(PowerMockRunner.class)

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

相关内容

  • 没有找到相关文章