#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
- Вертикаль
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()));
}
}
- Тестовый пример
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)
. Это переопределит любой тип инъекции, который вы используете.
Конкретно, вот что происходит:
- Mockito вводит макеты.
- Вы переопределяете инъекции Mockito с
injector.injectMembers(this)
помощью .
Поэтому не создавайте инжектор в start
методе: переместите его там, где это необходимо, в зависимости от различных используемых вами фреймворков.
Комментарии:
1. Спасибо за ответ, я использую vert.x, и я чувствую, что это то место, где мне нужна инъекция.
2. @AshutoshKumar ну, очевидно, это не так. Я объясняю последствия такого выполнения. Итак, вам нужно найти другое место.
3. я думаю, я могу сделать это и в другом месте, позвольте мне попробовать, если это сработает. Я вернусь к этому упражнению.