我正在尝试编写单元测试用例来使用一些mockito作为模拟框架来测试我的代码,在这之间我遇到了一个问题,我无法模拟我在测试类中使用Google Guice进行的注入(inject)。
我尝试直接注入(inject)对象,它有效,但 Google Injection 没有成功。
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();
});
});
}
}
使用这段代码,不会发生对 DataCreation 的模拟,并且代码流全部通过函数调用进行,我从代码中获得实际结果,而不是模拟的结果。
最佳答案
基本上,您有一个在发出请求时创建的注入(inject)器,并且使用该注入(inject)器是因为您使用 requestInjection(this)
。这将覆盖您使用的任何类型的注入(inject)。
具体来说,发生的事情是这样的:
- Mockito 注入(inject)模拟。
- 您可以使用
injector.injectMembers(this)
覆盖 Mockito 的注入(inject)。
因此,不要在 start
方法中创建注入(inject)器:根据您使用的各种框架将其移动到适当的位置。
关于java - 我如何在单元测试中使用 Mockito 或任何 Mocking 框架来模拟 Guice 注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55757232/