0

I would like to mock io.vertx.ext.jdbc.JDBCClient to unit-test the below verticle code:

class A {

    private final Helper help = new Helper();

    public JsonObject checkEmailAvailability(String email, JDBCClient jdbc) throws SignUpException {
        JsonObject result = new JsonObject();
        jdbc.getConnection(conn -> help.startTx(conn.result(), beginTans -> {
            JsonArray emailParams = null;
            emailParams = new JsonArray().add(email);
            System.out.println(email);
            help.queryWithParams(conn.result(), SQL_SELECT_USER_EMAIL, emailParams, res -> {
                if (res.getNumRows() >= 1) {
                    result.put("message", "Email already registered");
                }
            });
        }));
        return result;
    }
}
tmarwen
  • 15,750
  • 5
  • 43
  • 62
Anand
  • 1
  • 3

2 Answers2

0

You can use Mockito to mock your jdbc behavior. Let's say you want to test how you verticle behave when res returns one row.

Mock your jdbc:

jdbc = Mockito.mock(JDBCClient.class);

Then you have to mock a ResultSet object:

ResultSet res = Mockito.mock(ResultSet.class);
Mockito.when(res.getNumRows()).thenReturn(1);

Then you have to mock the AsyncResult object who is in charge to return res:

AsyncResult<ResultSet> asyncResultResultSet = Mockito.mock(AsyncResult.class);
Mockito.when(asyncResultResultSet.succeeded()).thenReturn(true);
Mockito.when(asyncResultResultSet.result()).thenReturn(res);

Then you have to mock the SQLConnection object who is in charge to return asyncResultResultSet. Use Answer to grab the handler and force it to return your mock:

SQLConnection sqlConnection = Mockito.mock(SQLConnection.class);
Mockito.doAnswer(new Answer<AsyncResult<ResultSet>>() {
  @Override
  public AsyncResult<ResultSet> answer(InvocationOnMock arg0) throws Throwable {
    ((Handler<AsyncResult<ResultSet>>) arg0.getArgument(2)).handle(asyncResultResultSet);
    return null;
  }
}).when(sqlConnection).queryWithParams(Mockito.any(), Mockito.any(), Mockito.any());

Then you have to mock the AsyncResult object who is in charge to return the sqlConnection. Again, Answer helps:

AsyncResult<SQLConnection> sqlConnectionResult = Mockito.mock(AsyncResult.class);
Mockito.when(sqlConnectionResult.succeeded()).thenReturn(true);
Mockito.when(sqlConnectionResult.result()).thenReturn(sqlConnection);
Mockito.doAnswer(new Answer<AsyncResult<SQLConnection>>() {
  @Override
  public AsyncResult<SQLConnection> answer(InvocationOnMock arg0) throws Throwable {
    ((Handler<AsyncResult<SQLConnection>>) arg0.getArgument(0)).handle(sqlConnectionResult);
    return null;
  }
}).when(jdbc).getConnection(Mockito.any());

Here you are. It is a bunch of code but you can mock multiple ResultSet object and use them with the asyncResultResultSet by chaining multiple thenReturn:

Mockito.when(asyncResultResultSet.result()).thenReturn(res1).thenReturn(res2) ...;

Try not to test vertx.io.

Here is my complete solution if you want to find dependencies. I also use Powermock with VertxUnit to run my verticle.

Francesco
  • 1,742
  • 5
  • 44
  • 78
  • 1
    You should provide full solution explanation pointed with external links and not simple links. – tmarwen Mar 21 '18 at 09:33
0

To mock the JDBCClient in vertx using mockito ..add dependency testCompile "io.vertx:vertx-codegen:3.2.1"

Otherwise you will get error as . Cannot mock static