【问题标题】:How to create mock instance of Autowired component in Vert.x如何在 Vert.x 中创建 Autowired 组件的模拟实例
【发布时间】:2020-04-03 02:19:16
【问题描述】:

我正在尝试在Verticle 内创建autowired 类的模拟实例,但我将其设为空。对于同步代码,工作方式看起来对Vert.x 没有用。

垂直是:

    @Component
    public class MyVerticle extends AbstractVerticle{

    @Autowired
    private ServiceExecutor serviceExecutor;

    @Override
    public void start() throws Exception {
        super.start();
        vertx.eventBus().<String>consumer("address.xyz").handler(handleRequest());
    }

    private Handler<Message<String>> handleRequest() {
        return msg -> {
            getSomeData(msg.body().toString())
            .setHandler(ar -> {
                if(ar.succeeded()){
                    msg.reply(ar.result());
                }else{
                    msg.reply(ar.cause().getMessage());
                }
             });
        };
    }

    private Future<String> getSomeData(String inputJson) {
        Promise<String> promise = Promise.promise();
        String data = serviceExecutor.executeSomeService(inputJson); // Getting NPE here. serviceExecutor is coming as null when trying to create mock of it using Mockito.when.
        promise.complete(data);
        return promise.future();    
     }
  }

依赖组件是:

@Component
public class ServiceExecutor {

    public String executeSomeService(String input){
        return "Returning Data";
    }
}

测试用例是:

import static org.mockito.Mockito.when;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import io.vertx.core.Vertx;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;

@RunWith(VertxUnitRunner.class)
public class MyVerticleTest {

    @Mock
    private ServiceExecutor serviceExecutor;

    private Vertx vertx;

    @Before
    public void setup(TestContext ctx){
        MockitoAnnotations.initMocks(this);
        Async async = ctx.async();
        this.vertx = Vertx.vertx();
        vertx.deployVerticle(MyVerticle.class.getName(), h -> {
            if(h.succeeded()){
                async.complete();
            }else{
                ctx.fail();
            }
        });
    }

    @Test
    public void test_consumption(TestContext ctx) {
        Async async = ctx.async();
        when(serviceExecutor.executeSomeService(Mockito.anyString())).thenReturn("Returning Data");
        vertx.eventBus().request("address.xyz","message", h ->{
            if(h.succeeded()){
                ctx.assertEquals("Returning Data",h.result().body().toString());
                async.complete();
            }else{
                ctx.fail(h.cause());
            }
        });
    }
}

如果我不使用autowired 实例调用方法来获取日期,则上面的测试用例效果很好。但是如果使用它(我必须这样做才能获取数据),当尝试使用 serviceExecutor 对象作为模拟对象时,它会在 MyVerticle-&gt;getSomeData() 方法上提供 NPE。这种方法对于同步代码流非常有效,但对于Vert.x 似乎无济于事。所以这里需要帮助来模拟autowired 内的serviceExecutor 实例Verticle

【问题讨论】:

  • 您可以在设置方法中使用@InjectMocks private MyVerticle myVerticle;vertx.deployVerticle(myVerticle, options, ctx.asyncAssertSuccess()); 之类的东西来代替lamda 表达式。这对你有用吗?

标签: junit vert.x junit5 vertx-verticle


【解决方案1】:

在你的 MyVerticle 中添加一个构造函数

public MyVerticle(ApplicationContext context) {
    context.getAutowireCapableBeanFactory().autowireBean(this);
}

并部署您的verticle,例如 vertx.deployVerticle(new MyVerticle(context),...

我在部署 Verticle 时有应用程序上下文,这就是我在构造函数中传递的内容。检查这是否适合您。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-11
    • 2010-11-27
    • 2020-02-27
    • 2016-02-17
    • 1970-01-01
    • 2022-01-12
    • 2021-03-11
    • 1970-01-01
    相关资源
    最近更新 更多