【问题标题】:Vertx Mock an async method with Handler<AsyncResult<>> argumentVertx 使用 Handler<AsyncResult<>> 参数模拟异步方法
【发布时间】:2018-03-15 05:07:27
【问题描述】:

我有这个数据访问接口:

public interface UserDao {

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

}

它被用在这样的服务中:

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 类的 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();

}

我该怎么做?它不符合正常的 Mockito 模式 when(serviceMock.method(any(Argument.class))).thenAnswer(new Result()) 因为 mockResult 不是从每个说的方法,但通过处理程序。

【问题讨论】:

  • 只是一个友好的评论,当涉及到 DAO 层时,沿着发送Future 的这条路线,当代码库开始增长时,事情真的变得难以理解和解释,如果你真的刚刚从你的项目开始,我的建议是使用Reactive Java 来处理这些东西。如果你愿意,我绝对可以为你添加描述事物的代码 sn-p。

标签: testing mocking mockito vert.x


【解决方案1】:

存根函数。

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());

【讨论】:

    【解决方案2】:

    您可以使用 ArgumentCaptor 检查是否使用非空处理程序调用了 loadUsers()。 ArgumentCaptor 让您可以访问处理程序 您可以将准备好的结果传递给它(成功或失败的结果)

    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);
    

    【讨论】:

      【解决方案3】:

      也模拟Handler

      Handler mockedHandler = mock(Handler.class);
      when(mockedHandler.result()).thenReturn(mockResult);
      when(userDao.loadUsers(any(Handler.class))).thenReturn(mockedHandler);
      

      【讨论】:

      • 这不起作用,因为处理程序不是由 loadUsers 方法返回的。这就是我问题的重点。请参阅我的问题的最后一句话。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-09
      • 1970-01-01
      • 2022-01-04
      • 2019-03-31
      • 2013-08-25
      相关资源
      最近更新 更多