Mock an async method with Handler<AsyncResult<>> argument

921 views
Skip to first unread message

vahid....@industrieit.com

unread,
Mar 14, 2018, 8:30:34 PM3/14/18
to vert.x
Sorry if it's a newbie question but I could not find any example for it out there. I think best I could explain it through an example. 

I have this data access interface:

public interface UserDao {

void loadUsers(Handler<AsyncResult<List<User>>> handler);

}

It is used in a service like this:

public class UserService {

private UserDao userDao;

public UserService(UserDao UserDao) {
this.userDao = userDao;
}

public void getUsers(Future<List<User>> future) {
userDao.loadUsers( ar ->{
if (ar.succeeded()){
List<User> users = ar.result();
// process users
future.complete(users);
}else {
// handle the error
}
});
}
}

Now my intention is to unit test my service and mock the data access layer. I want to return a fixed set of results every time getUsers method of UserDao class is called. 


@Test
public void testGetUsers(TestContext context) {

Async async = context.async();

UserDao mockUserDao = Mockito.mock(UserDao.class);

UserService userService = new UserService(mockUserDao);
List<User> mockResult = Arrays.asList(new User(), new User());

/* (?) How to make mockUserDao return mockResult through its Handler argument? */

Future<List<User>> future = Future.future();
userService.getUsers(future);
future.setHandler(ar -> {
assertEquals(2, ar.result().size());
async.complete();
});

async.awaitSuccess();

}

How can I do that? It does not fit the normal Mockito pattern when(serviceMock.method(any(Argument.class))).thenAnswer(new Result()) as mockResult is not returned from the method per say but through the handler.



Thomas SEGISMONT

unread,
Mar 15, 2018, 9:59:09 AM3/15/18
to ve...@googlegroups.com
Try:

when(mockUserDao.loadUsers(any(XXX.class)).thenAnswer(Future.<List<User>>succeededFuture(mockResult));

This email is confidential and intended solely for the person(s) to whom it is addressed.

--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+unsubscribe@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/80be540f-46b0-440f-9b39-1b0bf589de73%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

vahid....@industrieit.com

unread,
Mar 15, 2018, 10:47:55 PM3/15/18
to vert.x
Thanks Thomas but it won't work because the Future/Handler is NOT returned from the loadUsers() method. That's actually the point of this question.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.

John Warner

unread,
Mar 16, 2018, 4:58:22 AM3/16/18
to vert.x
Mockito provides a couple of ways of doing what you want. One is the:

Mockito.doAnswer(invocation->{invocation.getArgument(0).doSomething}).when(mockDao).loadUsers(any());

structure. You can grab what is passed into your mock's method from the invocation and then do whatever you like with it. I know it's called doAnswer, but it's not actually returning anything. 

The other is to use an ArgumentCaptor and Mockito verify. So something like:

@ArgumentCaptor
ArgumentCaptor<AsyncResult<Handler<List<User>>> asyncResultCaptor;
...
Mockito.verify(mockDao).loadUsers(asyncResultCaptor.capture());
AsyncResult<Handler<List<User>>> result = asyncResultCaptor.getValue();

Then you can do whatever you like with it. 

Sorry I don't have time to put together proper examples of this, but hopefully this makes sense.

Thomas SEGISMONT

unread,
Mar 16, 2018, 5:28:08 AM3/16/18
to ve...@googlegroups.com
Ha I see now. Sorry I totally missed the point...

To unsubscribe from this group and stop receiving emails from it, send an email to vertx+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages