Java单元测试:模拟带有谓词参数的方法

8

我有两个类:

ClassA {
   public String methodA(String accountId, Predicate<User> predicate) {
      // more code
   }; 
}

ClassB {
  methodB(){
    ClassA objectA = new ClassA();
    objectA.methodA("some id", PredicatesProvider.isUserValid());
    // more code ...
  }
}

class PredicatesProvider {
   static Predicate<User> isUserValid(){
   return (user) -> {
      return  user.isValid();
   }
}

在我的单元测试中,我需要模拟ClassA,因此我使用了Mockito的mock方法,如下所示:
ClassA mockObjectA = Mockito.mock(ClassA.class);
Mockito.when(mockObjectA).methodA("some id", PredicatesProvider.isUserValid()).thenReturn("something");

Mockito无法找到匹配的签名。

The java.lang.AssertionError: expected:<PredicatesProvider$$Lambda$5/18242360@815b41f> but was:<PredicatesProvider$$Lambda$5/18242360@5542c4ed>

这是我试图实现的简化版。我猜这是谓词的equals()函数的问题。有没有办法模拟一个带有谓词参数的方法?
谢谢。
1个回答

14

我看到有四种可能的解决方案:

  1. 从您的 isUserValid() 方法中始终返回相同的 Predicate 实例。由于 Predicate 是状态无关的,这不是问题。

  2. 将 Predicate 实现为真正的类,并实现 equals() 和 hashCode()。但与第一个解决方案相比,这是过度设计。

  3. 使用 matcher:

     Mockito.when(mockObjectA).methodA(Mockito.eq("some id"), Mockito.<Predicate<User>>anyObject()).thenReturn("something");
    
    不要使用静态方法创建谓词,而是使用可注入的工厂,这样您可以模拟和验证它:
  4. PredicatesProvider mockPredicatesProvider = mock(PredicatesProvider.class);
    Predicate<User> expectedPredicate = (u -> true);
    when(mockPredicatesProvider.isUserValid()).thenReturn(expectedPredicate);
    when(mockObjectA).methodA("some id", expectedPredicate).thenReturn("something");
    

我想进一步研究第一个解决方案,因为第三种方式有点放松了验证,并且不需要完全匹配。 - beijxu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接