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

阿舒托什·夏尔马(Ashutosh Sharma):

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

我尝试了直接注入对象,它可以工作,但是使用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中
    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();
      });
    });
  }

}

有了这段代码,DataCreation的模拟就不会发生,并且代码流将遍历整个函数调用,而我从代码中得到的是实际的结果,而不是模拟的结果。

OlivierGrégoire:

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

具体来说,这是正在发生的事情:

  1. Mockito注入模拟。
  2. 您可以使用覆盖Mockito的注入injector.injectMembers(this)

因此,请勿在该start方法中创建注入器:根据您使用的各种框架,将其移动到适当的位置。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Resteasy和Google Guice:如何在@Injection中使用多个@ApplicationPath和资源?

如何在Python中使用Mockito编写单元测试

如何在Mockito的单元测试中模拟LocalCache

如何模拟要使用JUnit + Mockito进行单元测试的服务中使用的类

单元测试如何使用Mockito模拟存储库

如何使用Mockito模拟静态方法以进行单元测试

如何在Android Studio的单元测试中使用Mockito / Hamcrest

如何在Angular 4中使用提供程序模拟组件?- 单元测试

模拟 API 响应时如何在单元测试中使用 JSON 文件

如何在与Jest的react-native中使用模拟的fetch()对API调用进行单元测试

如何在Angular 8中使用对象模拟数组数据以进行单元测试

如何在AngularJS单元测试中使用$ httpBackend注入和模拟$ http?

如何在 Grails 单元测试中使用 Spock 模拟 passwordEncoder

如何在 Laravel 5 中使用 Codeception 在单元测试中模拟身份验证用户?

使用 Mockito 对基于 Guice 的类进行单元测试

如何在Node.js应用程序中使用sql-injection包?

如何使用模拟框架模拟龙卷风协程函数进行单元测试?

如何使用 Visual Studio 单元测试框架或 NUnit 框架在 C# 中模拟对象?

测试Jersey应用程序,使用Jersey Injection内置框架(HK2)注入类

使用Scala与Injection进行功能测试游戏框架的更好方法是什么

如何使用 Mockito 通过单元测试?

如何在Mockito + J单元测试中捕获或模拟意外的异常?

春季-使用模拟单元测试-如何在服务单元测试中模拟自定义收集器

如何在Microsoft Dependency Injection中注册Automapper 5.0?

如何在TEST-INJECTION之外获取变量?

如何在单元测试中使用android依赖项?

如何在单元测试中使用熊猫数据框

如何在Mocha异步单元测试中使用afterEach?

如何在单元测试中使用断言?