Quarkus 依赖注入

时间:2021-06-16 16:05:51

标签: java mockito quarkus

我是 Quarkus 的新手,我正在尝试为名为 DummyReceiver 的对象编写测试。我知道 Quarkus 提供 @Mock 和其他方法来创建模拟对象,但这有一个缺点,即所有测试中的每个实例都将被替换为相同的模拟,我不希望那样。所以我尝试做一个简单的依赖注入。

以下是最重要的配置:

<properties>
    <compiler-plugin.version>3.8.1</compiler-plugin.version>
    <maven.compiler.parameters>true</maven.compiler.parameters>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <quarkus-plugin.version>1.13.3.Final</quarkus-plugin.version>
    <quarkus.platform.artifact-id>quarkus-universe-bom</quarkus.platform.artifact-id>
    <quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
    <quarkus.platform.version>1.13.3.Final</quarkus.platform.version>
    <wiremock.version>2.28.0</wiremock.version>
    <spotless.version>2.11.0</spotless.version>
    <surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
</properties>
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-junit5</artifactId>
  <scope>test</scope>
</dependency>

我的代码是这样的:

public interface DummyDependencyInterface {
  void store(String id);
}
import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class DummyDependency implements DummyDependencyInterface {

  public void store(String id) {
    System.out.println("DummyDependency stored: " + id);
  }
}
public class DummyMessage {

  private final String scannerInput;

  public DummyMessage(String scannerInput) {
    this.scannerInput = scannerInput;
  }

  public String getScannerInput() {
      return this.scannerInput;
    }
}
import ch.scs.mbv.vega.websocket.ScannerSocketMessage;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;

@ApplicationScoped
public class DummyReceiver {

  private DummyDependencyInterface dependency;

  public DummyReceiver(DummyDependencyInterface dependency) {
    System.out.println("DummyReceiver created with " + dependency.getClass().getName());
    this.dependency = dependency;
  }

  public void onProcessScannerMessage(@Observes DummyMessage message) {
    String scan = message.getScannerInput();
    dependency.store(scan);
  }
}

然后我像这样进行测试:

import java.util.concurrent.LinkedBlockingDeque;

public class DummyDependencyMock implements DummyDependencyInterface {

  public LinkedBlockingDeque<String> ids = new LinkedBlockingDeque<>();

  public void store(String id) {
    ids.add(id);
    System.out.println("DummyDependencyMock stored: " + id);
  }
}
import io.quarkus.test.junit.QuarkusTest;
import java.util.concurrent.TimeUnit;
import javax.enterprise.event.Event;
import javax.inject.Inject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

@QuarkusTest
public class DummyReceiverTest {

  @Inject
  Event<DummyMessage> messageEvent;

  private DummyDependencyMock mock;
  private DummyReceiver receiver;

  @BeforeEach
  public void setup() {
    mock = new DummyDependencyMock();
    receiver = new DummyReceiver(mock);
  }

  @Test
  public void test() throws Exception {
    String id = "123";

    messageEvent.fire(new DummyMessage(id));

    String storedId = mock.ids.poll(1, TimeUnit.SECONDS);
    Assertions.assertEquals("123", storedId);
  }
}

输出显示

DummyReceiver created with scanning.DummyDependencyMock
DummyReceiver created with scanning.DummyDependency_ClientProxy
DummyDependency stored: 123
org.opentest4j.AssertionFailedError: 
Expected :123
Actual   :null

有谁知道出了什么问题以及如何解决?有没有更好的方法来做到这一点?任何建议表示赞赏!

更新:解决方案示例

以下示例用于说明目的,显示了我能想到的最简单的可能解决方案。 Example 是我们要测试的类:

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class Example {

  private Delegate delegate;

  Example(Delegate delegate) {
    this.delegate = delegate;
  }

  public void doIt() {
    delegate.execute();
  }
}

我们要模拟的依赖项称为 Delegate:

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class Delegate {

  public void execute() {

  }
}

我们可以编写以下测试来验证Example调用了Delegate的方法execute

import static org.mockito.Mockito.verify;

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

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

  @Mock
  Delegate delegateMock;

  @InjectMocks
  Example example;

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

  @Test
  public void test() {
    example.doIt();
    verify(delegateMock).execute();
  }
}

2 个答案:

答案 0 :(得分:1)

您在测试中创建的 DummyReceiver 不会以任何方式为应用程序的其余部分所知。

如果你想模拟 DummyDependencyMock,在 Quarkus 中有多种方法可以做到,但 @io.quarkus.test.junit.mockito.InjectMock 是迄今为止最简单的。

你的代码看起来像

@QuarkusTest
public class DummyReceiverTest {

  @Inject
  Event<DummyMessage> messageEvent;

  @InjectMock
  private DummyDependencyMock mock;


  @Test
  public void test() throws Exception {
    String id = "123";

    messageEvent.fire(new DummyMessage(id));

    String storedId = mock.ids.poll(1, TimeUnit.SECONDS);
    Assertions.assertEquals("123", storedId);
  }
}

请注意,使用 @InjectMock 仅更改特定测试的模拟 - 请参阅 this 了解更多详情

答案 1 :(得分:0)

geoand 几乎是对的,他的回答帮助我弄清楚了其余的 - 谢谢!!!这是对我有用的代码:

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

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

  @Inject
  Event<DummyMessage> messageEvent;

  @InjectMock
  private DummyDependencyMock mock;

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

  @Test
  public void test() throws Exception {
    String id = "123";

    messageEvent.fire(new DummyMessage(id));

    String storedId = mock.ids.poll(1, TimeUnit.SECONDS);
    Assertions.assertEquals("123", storedId);
  }
}
相关问题