任何避免此Mockito测试的try/catch阻塞的方法



我正在使用Mockito模拟一些对象并测试我的WebSocket消息发送器服务。send方法接受一个org.springframework.web.socket.WebSocketSession和一个消息,并返回一个CompletableFuture

在传递给CompletableFuturethenAccept()方法的lambda中,我验证了session.sendMessage()方法已被使用期望值调用:

WebSocketSession session = mockWebSocketSession();
TextMessage expectedMessage = new TextMessage("test text message");
sender.sendStringMessage(session, "test text message").thenAccept(nil -> {
    try{ // this is what I am talking about
        verify(session).sendMessage(expectedMessage);
    }catch(IOException e){}
});

由于sendMessage()方法抛出IOException,我被迫在lambda内部的调用周围添加一个无用的try/catch块。这是不必要的啰嗦。

您可以尝试使用榴莲库

foodOnPlate.forEach(Errors.suppress().wrap(this::eat));
list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c)));

或扩展consumer self

@FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T> {
    @Override
    default void accept(final T elem) {
        try {
            acceptThrows(elem);
        } catch (final Exception e) {
            /* Do whatever here ... */
            System.out.println("handling an exception...");
            throw new RuntimeException(e);
        }
    }
    void acceptThrows(T elem) throws Exception;
}
//and then pass
thenAccept((ThrowingConsumer<String>) aps -> {
  // maybe some other code here...
throw new Exception("asda");
})

我将以这种方式重做您的测试

final String testMessage = "test text message";
WebSocketSession session = mockWebSocketSession();
sender.sendStringMessage(session, testMessage).get(); // will wait here till operation completion
verify(session).sendMessage(new TextMessage(testMessage));

并将IOException添加到测试方法签名中。

这个解决方案解决了两个问题:

  1. 你的测试代码更干净,所有的断言和验证都在你的测试方法的末尾在一个地方;
  2. 解决方案解决了竞争条件,当您的测试可能无声地完成并且绿色,但您在CompletableFuture lambda中的玻璃化甚至被执行

根据我的评论,我将做这样的事情:

public void myMethod() {
  try{ // this is what I am talking about
    verify(session).sendMessage(expectedMessage);
  }catch(IOException e) {}
}

然后:

sender.sendStringMessage(session, "test text message").thenAccept(nil -> myMethod());

复制这个?Java 8: lambda表达式中的强制检查异常处理。为什么是强制性的,而不是可选的?

您在测试类中,因此只需将throws IOException添加到您的方法。这样,如果这个方法引发IOException,在这种情况下,它意味着你的测试将失败。

或者你也可以说你的方法预计会抛出IOException,

类似于:

@Test(expected = IOException.class)
public void yourTestCaser(){
   //... 

有了这个,它看起来像这样:

sender.sendStringMessage(session, "test text message").thenAccept(nil -> 
{ verify(session).sendMessage(expectedMessage); });

相关内容

  • 没有找到相关文章

最新更新