无法使用 Quarkus 进行模拟,NullPointer 异常且无法找到相关导入

问题描述 投票:0回答:3

我正在尝试使用 Mockito 为 Quarkus 编写单元测试,但我无法模拟事物。

这是一个最小的(不是)工作示例:

package com.my.package;

import io.quarkus.test.junit.QuarkusTest;
import org.mockito.Mockito;
import org.mockito.Mock;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

@QuarkusTest
public class LoadCalculatorServiceTest {

    public class Foobar {
        public int baz;
        public void setBaz(int baz) {
            this.baz = baz;
        }
        public int getBaz() {
            return this.baz;
        }
    }

    @Mock
    Foobar foobar;
    // Foobar foobar = new Foobar(); // doesn’t work either

    @Test
    public void myTest() {
        Mockito.when(foobar.getBaz()).thenReturn(4); // NullPointer
        Assertions.assertEquals(4,foobar.getBaz());
    }
}

测试在 NullPointer 上崩溃。

我读到这些问题可以通过用

@RunWith(MockitoJUnitRunner.class)
@ExtendWith(MockitoExtension.class)
注释测试来解决(出于某种原因,我期望
@QuarkusTest
无论如何都会这样做?),但是我找不到正确的导入来加载它们。

我尝试了

org.junit.jupiter.api.MockitoExtension
org.junit.runner.RunWith
和各种变体,但没有成功。

这是我的

pom.xml
的相关部分:

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5-mockito</artifactId>
      <scope>test</scope>
    </dependency>

我错过了什么?

java unit-testing junit mockito quarkus
3个回答
7
投票

我想原始代码适用于简单风格的模拟:

Foobar foobar = Mockito.mock(Foobar.class);

所以问题实际上是如何使

@Mock
注释起作用?为此需要几件事:

  1. JUnit5 中的

    @RunWith
    注释已被 @ExtendWith 替换(或者我们应该说
    升级
    )。可以使用
    import org.junit.jupiter.api.extension.ExtendWith;
    将其导入到 Quarkus 中。

  2. @RunWith
    通常用作
    @ExtendWith(MockitoExtension.class)
    。可以使用
    import org.mockito.junit.jupiter.MockitoExtension;
    将 MockitoExtension 导入到 Quarkus 中。 注意
    mockito-junit-jupiter
    依赖项(来自
    org.mockito
    组)必须添加到
    pom.xml
    ,因为
    quarkus-junit5-mockito
    不依赖于它

  3. 模拟必须在测试之前由

    MockitoAnnotations.initMocks()
    初始化。请注意,虽然使用
    @BeforeAll
    作为设置函数似乎更有意义,但显然这不是此注释的重点,应该使用
    @BeforeEach
    (前者需要设置是静态的,而 IIUC 需要设置无论如何,函数将在每次测试之前调用)。

  4. 最后

    @Mock
    注释应该可以工作。

总而言之,原始代码将变为:

package com.my.package;

import io.quarkus.test.junit.QuarkusTest;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;

@QuarkusTest
@ExtendWith(MockitoExtension.class)
public class LoadCalculatorServiceTest {

    public class Foobar {
        public int baz;
        public void setBaz(int baz) {
            this.baz = baz;
        }
        public int getBaz() {
            return this.baz;
        }
    }

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

    @Mock
    Foobar foobar;

    @Test
    public void myTest() {
        Mockito.when(foobar.getBaz()).thenReturn(4);
        Assertions.assertEquals(4,foobar.getBaz());
    }
}

pom.xml
添加以下内容:

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-junit-jupiter</artifactId>
  <scope>test</scope>
</dependency>

0
投票

我正在使用quarkus 1.8.1.Final,使用mockito 3.6.0,我对@Mock注释有同样的问题,我遵循了Skippy le Grand Gourou的答案,但它不起作用,所以我删除了@QuarkusTest注解,并删除de MockitoAnnotations.initMocks(this)方法,我的mockito版本已经弃用了这个,然后用@Mock注解运行测试。我是 Quarkus 的新手,所以我不太清楚删除 @QuarkusTest 的副作用


0
投票

当您使用

MockitoExtension
扩展它时,不需要
@QuarkusTest
的存在。只需在代码中包含
@ExtendWith(MockitoExtension.class)
并排除
@QuarkusTest
就可以了。

但是,如果您打算保留

@QuarkusTest
,则必须使用 Quarkus@InjectMock 来实现此目的。
@InjectMock
有助于创建 Mockito 模拟。因此,修改后的代码如下所示:

@QuarkusTest
public class LoadCalculatorServiceTest {
    @ApplicationScoped
    static class Foobar {
        public int baz;
        public void setBaz(int baz) {
            this.baz = baz;
        }
        public int getBaz() {
            return this.baz;
        }
    }

    @InjectMock
    Foobar foobar;

    @Test
    public void myTest() {
        when(foobar.getBaz()).thenReturn(4); // NullPointer
        Assertions.assertEquals(4,foobar.getBaz());
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.