Как я могу имитировать внедрение Guice с помощью Mockito или любого фреймворка-макета в моем модульном тестировании?

#java #mockito #guice #vert.x

#java #mockito #guice #vert.x

Вопрос:

Я пытаюсь написать модульный тестовый пример, чтобы протестировать свой код с помощью некоторого mockito в качестве фреймворка-макета, между ними я столкнулся с проблемой, когда я не могу имитировать внедрение, которое я сделал с помощью Google Guice в моем тестовом классе.

Я попытался напрямую внедрить объект, он работает, но не повезло с внедрением Google.

 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
}

  

Тестовый класс для тестирования вышеуказанного 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
    1. Вертикаль
 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();
      });
    });
  }

}

  

С этим фрагментом кода насмешка над созданием данных не происходит, и поток кода проходит через вызов функции, и я получаю фактический результат из моего кода, а не издевательский.

Комментарии:

1. Ни один из опубликованных вами кодов не будет скомпилирован. Опубликуйте полный, достоверный, минимальный пример, воспроизводящий проблему.

2. Действительно ли это нужно?, Я думаю, я уверен, что мой вопрос имеет смысл. Тем не менее, если вы хотите, чтобы я опубликовал, что я могу это сделать, но это все вместе проект, и он будет немного длинным 🙂

3. Нам не нужен ваш фактический, длинный код. Нам нужен полный минимальный пример, воспроизводящий проблему. В опубликованном вами коде так много проблем, что мы не можем знать, какие из них предназначены для сокращения кода, а какие из них являются фактическими ошибками.

4. Конечно, я опубликую минимальный код, воспроизводящий проблему. Большое спасибо за предложение.

5. Добавлен код, пожалуйста, проверьте сейчас

Ответ №1:

По сути, у вас есть инжектор, который создается при выполнении запроса, и этот инжектор используется, потому что вы используете requestInjection(this) . Это переопределит любой тип инъекции, который вы используете.

Конкретно, вот что происходит:

  1. Mockito вводит макеты.
  2. Вы переопределяете инъекции Mockito с injector.injectMembers(this) помощью .

Поэтому не создавайте инжектор в start методе: переместите его там, где это необходимо, в зависимости от различных используемых вами фреймворков.

Комментарии:

1. Спасибо за ответ, я использую vert.x, и я чувствую, что это то место, где мне нужна инъекция.

2. @AshutoshKumar ну, очевидно, это не так. Я объясняю последствия такого выполнения. Итак, вам нужно найти другое место.

3. я думаю, я могу сделать это и в другом месте, позвольте мне попробовать, если это сработает. Я вернусь к этому упражнению.