我如何在单元测试中使用Mockito或任何Mocking框架来模拟Guice Injection?

问题描述 投票:1回答:1

我正在尝试使用一些mockito作为模拟框架来编写单元测试用例来测试我的代码。在我之间我遇到了一个问题,我无法在我的测试类中使用Google Guice模拟注入。

我尝试直接注入该对象,它有效但谷歌注入没有运气。

class SomeClassToCreateWiskey{
// Some Service
@Inject
@Named("dataCreation")
DataCreation dataCreation;

public apis(){
    Injector injector = Guice.createInjector(new DataCreationModel());
    injector.injectMembers(this);
    int port = config().getInteger("http.port", 8080);
    Router router = Router.router(vertx);
    router.route("/api/getAll").handler(this::getAll);
  }
// getAll method will return some json result
}

Test Class to test above API

class SomeClassToCreateWiskeyTest{
     @Mock
     private DataCreation dataCreation;
     // setting up before and after config
     @Before
     MockitoAnnotations.initMocks(this);
       ......
     @After
       ......
     @Test
     public void testGetAll(){
       Map<Integer, Whisky> dataSets = new LinkedHashMap<>();
       Whisky w1 = new Whisky("Bowmore 15 Years Laimrig", "Scotland, Islay");
       Whisky w2 = new Whisky("Talisker 57° kya h", "Scotland, Island");
      Async async = context.async();
      dataSets.put(w1.getId(), w1);
      dataSets.put(w2.getId(), w2);
      when(dataCreationDao.getData()).thenReturn(dataSets);
      when(dataCreation.getData()).thenReturn(dataSets);
      HttpClient client = vertx.createHttpClient();
      client.getNow(port, "localhost", "/api/getAll", response -> {
      response.bodyHandler(body -> {
        System.out.println(body.toString());
        client.close();
        async.complete();
          });
       });

     } 

}

在其中一条评论中添加实际代码:

  • 该项目位于Vert.x中 Verticle
package com.testproject.starter.verticles;

import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.testproject.starter.model.DataCreationModel;
import com.testproject.starter.services.DataCreation;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.json.Json;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;

public class ErrorReproduction extends AbstractVerticle {
  @Inject
  @Named("dataCreation")
  DataCreation dataCreation;

  //DataCreation dataCreation = new DataCreationImpl();
  @Override
  public void start(Future<Void> startFuture) throws Exception {
    Injector injector = Guice.createInjector(new DataCreationModel());
    injector.injectMembers(this);
    int port = config().getInteger("http.port", 8080);
    Router router = Router.router(vertx);
    router.route("/api/getAll").handler(this::getAll);
    vertx.createHttpServer().requestHandler(router::accept)
      .listen(port,result -> startFuture.complete());
  }
  public void getAll(RoutingContext routingContext) {
    routingContext.response().putHeader("content-type", "application/json")
      .end(Json.encodePrettily(dataCreation.getData().values()));
  }
}

  1. 测试用例
package com.testproject.starter.verticles;

import com.testproject.starter.dao.DataCreationDao;
import com.testproject.starter.ppojo.Whisky;
import com.testproject.starter.services.DataCreation;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpClient;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.RunTestOnContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import java.io.IOException;
import java.net.ServerSocket;
import java.util.LinkedHashMap;
import java.util.Map;

import static org.mockito.Mockito.when;

@RunWith(VertxUnitRunner.class)
public class ErrorReproductionTest {
  Vertx vertx;
  int port;
  @Mock
  private DataCreation dataCreation;
  @Mock
  private DataCreationDao dataCreationDao;
  @Rule
  public RunTestOnContext rule = new RunTestOnContext();

  @Rule
  public MockitoRule mockitoRule = MockitoJUnit.rule();
  @InjectMocks
  private ErrorReproduction errVertical;

  @Before
  public void before(TestContext context) throws IOException {
    MockitoAnnotations.initMocks(this);
    ServerSocket socket = new ServerSocket(0);
    port = socket.getLocalPort();
    socket.close();
    DeploymentOptions options = new DeploymentOptions()
      .setConfig(new JsonObject().put("http.port", port));
    vertx = Vertx.vertx();
    rule.vertx().deployVerticle(errVertical, options, context.asyncAssertSuccess());
  }
  @After
  public void after(TestContext context) {
    vertx.close(context.asyncAssertSuccess());
  }
  @Test
  public void testGetAll(TestContext context){
    Map<Integer, Whisky> dataSets = new LinkedHashMap<>();
    Whisky w1 = new Whisky("Bowmore 15 Years Laimrig", "Scotland, Islay");
    Whisky w2 = new Whisky("Talisker 57° kya h", "Scotland, Island");
    Async async = context.async();
    dataSets.put(w1.getId(), w1);
    dataSets.put(w2.getId(), w2);
    when(dataCreationDao.getData()).thenReturn(dataSets);
    when(dataCreation.getData()).thenReturn(dataSets);
    HttpClient client = vertx.createHttpClient();
    client.getNow(port, "localhost", "/api/getAll", response -> {
      response.bodyHandler(body -> {
        System.out.println(body.toString());
        client.close();
        async.complete();
      });
    });
  }

}

使用这段代码,DataCreation的模拟没有发生,代码流全部通过函数调用,我从我的代码获得实际结果而不是模拟的。

java mockito guice vert.x
1个回答
1
投票

基本上,您有一个在执行请求时创建的注入器,并且因为您使用requestInjection(this)而使用该注入器。这将覆盖您使用的任何类型的注射。

具体来说,这是发生了什么:

  1. Mockito注入了嘲笑。
  2. 你用injector.injectMembers(this)覆盖Mockito的注射。

因此,不要在start方法中创建一个注入器:根据您使用的各种框架,在适当的位置移动它。

© www.soinside.com 2019 - 2024. All rights reserved.