Testing Vertx模拟具有处理程序的异步方法<;异步结果<&燃气轮机&燃气轮机;论点
我有这个数据访问接口:Testing Vertx模拟具有处理程序的异步方法<;异步结果<&燃气轮机&燃气轮机;论点,testing,mocking,mockito,vert.x,Testing,Mocking,Mockito,Vert.x,我有这个数据访问接口: public interface UserDao { void loadUsers(Handler<AsyncResult<List<User>>> handler); } 公共接口UserDao{ void loadUsers(处理程序); } 在这样的服务中使用: public class UserService { private UserDao userDao; public UserService(U
public interface UserDao {
void loadUsers(Handler<AsyncResult<List<User>>> handler);
}
公共接口UserDao{
void loadUsers(处理程序);
}
在这样的服务中使用:
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
}
});
}
}
公共类用户服务{
私有UserDao UserDao;
公共用户服务(UserDao UserDao){
this.userDao=userDao;
}
公共用户(未来){
userDao.loadUsers(ar->{
如果(ar.successed()){
列表用户=ar.result();
//进程用户
未来。完成(用户);
}否则{
//处理错误
}
});
}
}
现在,我打算对我的服务进行单元测试,并模拟数据访问层。每次调用UserDao类的getUsers方法时,我都希望返回一组固定的结果
@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();
}
@测试
公共void testGetUsers(TestContext上下文){
Async Async=context.Async();
UserDao mockUserDao=Mockito.mock(UserDao.class);
UserService UserService=newuserservice(mockUserDao);
List mockResult=Arrays.asList(new User(),new User());
/*(?)如何使mockUserDao通过其处理程序参数返回mockResult*/
Future=Future.Future();
getUsers(未来);
future.setHandler(ar->{
资产质量(2,ar.result().size());
async.complete();
});
async.waitsuccess();
}
我该怎么做?当(serviceMock.method(any(Argument.class)))时,它不符合正常的Mockito模式。然后,作为mockResult的应答(new Result())不是通过方法返回的,而是通过处理程序返回的。Mock
处理程序
Handler mockedHandler = mock(Handler.class);
when(mockedHandler.result()).thenReturn(mockResult);
when(userDao.loadUsers(any(Handler.class))).thenReturn(mockedHandler);
存根函数
public class TestUserDao implements UserDao {
void loadUsers(Handler<AsyncResult<List<User>>> handler) {
handler.apply(mockResult)
}
}
UserDao userDao = mock(UserDao.class, AdditionalAnswers.delegatesTo(new TestUserDao()));
verify(userDao).loadUsers(any());
公共类TestUserDao实现UserDao{
void loadUsers(处理程序){
handler.apply(mockResult)
}
}
UserDao UserDao=mock(UserDao.class,AdditionalAnswers.delegatesTo(newtestuserdao());
验证(userDao).loadUsers(any());
您可以使用ArgumentCaptor检查是否使用非空处理程序调用了loadUsers()。ArgumentCaptor允许您访问处理程序
您可以向其传递准备好的结果(成功或失败的结果)
AsyncResult yourResult=//成败
ArgumentCaptor captor=ArgumentCaptor.forClass(Handler.class);
Mockito.verify(userDao.loadUsers(captor.capture());
Handler=captor.getValue();
handler.handle(你的结果);
这不起作用,因为loadUsers方法没有返回处理程序。这就是我问题的全部要点。请看我问题中的最后一句话。只是一个友好的评论,当涉及到DAO层时,沿着发送Future
的路线,当代码库开始增长时,事情真的变得很难理解和解释,如果您真的刚刚开始您的项目,我的建议是使用reactivejava
。如果您愿意,我可以为您添加描述事物的代码片段。
AsyncResult<List<User>> yourResult = ... //success or failure
ArgumentCaptor<Handler<AsyncResult<List<User>>>> captor = ArgumentCaptor.forClass(Handler.class);
Mockito.verify(userDao).loadUsers(captor.capture());
Handler<AsyncResult<List<User>>> handler = captor.getValue();
handler.handle(yourResult);