如何对可调用的lambda表达式进行单元测试?

如何对可调用的lambda表达式进行单元测试?,lambda,mockito,powermockito,callable,Lambda,Mockito,Powermockito,Callable,我有一段Java代码需要用PowerMockito进行单元测试: public class MyClass { public Response someMethod() { Response response = Wrapper.wrap( () -> { return OtherClass.doSomething(); }); // .... do something else .... return Response; }

我有一段Java代码需要用PowerMockito进行单元测试:

public class MyClass {

  public Response someMethod() {

    Response response = Wrapper.wrap( () -> {
      return OtherClass.doSomething();
    });

    // .... do something else ....

    return Response;
  }

}
实际上,包装器做什么并不重要,但为了简单起见,它是:

public class Wrapper {

  public Response wrap(Callable<Response> callable) {
    // ...check something...
    return callable.call();
  }

}
公共类包装器{
公共响应包装(可调用可调用){
//…检查一下。。。
返回callable.call();
}
}

在单元测试中,我想模拟对
OtherClass.doSomething()
的调用并验证它是否被调用,但我不希望包装器实际执行lambda表达式之外的任何操作。如何实现这一点?

我不确定,但我相信您只是想模拟一个静态方法。您可以按照第一个答案中的示例进行操作:


对于每个调用,您都可以使用PowerMockito的verifyStatic方法,正如@staszko032已经指出的那样,您的问题不是lambda,而是静态方法调用-这通常是一个痛苦的问题。。。留下来测试。只要
Wrapper.wrap
(或者更可能的是,
Otherclass.doSomething()
)是一个静态调用,您就需要像PowerMockito这样的复杂工具。你不能期望抛出静态调用,仍然得到良好的测试代码-这不是它的工作原理,抱歉。就个人而言,我倾向于说PowerMockito是一个用来解决问题的工具,只是因为代码不好。重构(如果可能的话)应始终优先于PowerMockito或类似工具

因此,就我个人而言,我会重构它,例如,使包装器类不是静态的,而是向其中注入一个实例。这样,您就可以在测试中注入一个mock

当然,这实际上不会解决您的问题,因为您可以验证是否调用了wrap(…),甚至可以获得作为参数提供的lambda,但lambda将再次调用
Otherclass.doSomething()
,这同样很难测试。因此,在这里进行重构可能是更好的主意:插入Otherclass的实例,而不是静态调用,在测试中使用mock和bingo,您可以验证调用了
doSomething

public class MyClass {

  private OtherClass otherClassInstance; // setter/constructor/autowire/whatever     

  public Response someMethod() {

    Response response = Wrapper.wrap( () -> {
      return otherClassInstance.doSomething(); // now that's testable
    });

    // .... do something else ....

    return Response;
  }

}

我知道如何模拟静态呼叫。。。这里我关心的是捕获lambda表达式。lambda表达式似乎进行了静态调用,因此最后,要检查lambda,必须验证对
OtherClass.doSomething()
的静态调用是否完成。我的问题不是静态方法,而是lambda表达式。这不是我的第一次单元测试,也不是我第一次测试静态方法。以下是模拟静态调用的方式供将来参考:
mockStatic(OtherClass.class);when(OtherClass.doSomething())。然后返回(mockResponse)同样,PowerMock等工具只是因为代码不好才需要。坏代码的解决方案是重构,而不是抛出更多的坏代码。实际上,重写整个该死的代码库比开始重构更容易…:-(测试lambda表达式并不比测试其他代码更难。在您的情况下,只需了解它实际上是什么:接口的匿名实例是可调用的。当然,匿名实例不容易测试,但这里也适用相同的原则。如果重构是不可能的,您只能测试结果,这意味着静态模拟很可能,这让我想起了我的答案