【问题标题】:Java unit test mock a method with predicate as an argumentJava单元测试模拟一个以谓词为参数的方法
【发布时间】:2015-06-29 15:32:04
【问题描述】:

我有两个班级:

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 的模拟方法如下:

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() 函数的问题。知道如何模拟具有谓词参数的方法吗?

谢谢

【问题讨论】:

    标签: java-8 mockito predicate


    【解决方案1】:

    我看到了 4 种可能的解决方案:

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

    2. 将 Predicate 实现为一个真正的类,实现 equals() 和 hashCode()。但与第一个解决方案相比,这太过分了。

    3. 使用匹配器:

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

    【讨论】:

    • 我想进一步考虑第一个解决方案,因为#3 放松了验证并且不需要完全匹配。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-16
    • 1970-01-01
    • 2015-10-21
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多