Как создать макет компонента Autowired в Vert.x

Я пытаюсь создать фиктивный экземпляр класса, который autowired внутри Verticle, но я получаю его как ноль. Для синхронного кода способ, который работает, не подходит для 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 для вызова метода для получения даты. Но если он используется (что я должен сделать для получения данных), он дает NPE в MyVerticle->getSomeData() методе при попытке использовать объект serviceExecutor в качестве имитации. Этот подход очень хорошо работает для синхронного потока кода, но для Vert.x похоже, что он не поможет. Так что здесь нужна помощь, чтобы смоделировать autowired экземпляр serviceExecutor внутри Verticle.


person Nags    schedule 09.12.2019    source источник
comment
Вы можете использовать @InjectMocks private MyVerticle myVerticle; и что-то вроде vertx.deployVerticle(myVerticle, options, ctx.asyncAssertSuccess()); в методе настройки вместо выражения lamda. Это сработает для вас?   -  person Smile    schedule 10.12.2019


Ответы (1)


Добавьте конструктор в MyVerticle

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

и разверните свою вертикаль, например, vertx.deployVerticle (new MyVerticle (context), ...

У меня есть контекст приложения при развертывании вертикали, и это то, что я передаю в конструктор. Проверьте, работает ли это для вас.

person Ravi Lohan    schedule 02.03.2020