Я пытаюсь создать фиктивный экземпляр класса, который 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
.
@InjectMocks private MyVerticle myVerticle;
и что-то вродеvertx.deployVerticle(myVerticle, options, ctx.asyncAssertSuccess());
в методе настройки вместо выражения lamda. Это сработает для вас? - person Smile   schedule 10.12.2019