Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java unit test mock a method with predicate as an argument

I have two classes:

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

In my unit test, I need to mock ClassA, so I use Mockito's mock method like the following:

ClassA mockObjectA = Mockito.mock(ClassA.class);
Mockito.when(mockObjectA).methodA("some id", PredicatesProvider.isUserValid()).thenReturn("something");

Mockito couldn't find a signature match.

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

This is kind of a simplified version of what I am trying to achieve. I guess this is a problem with the equals() function of predicate. Any idea how to mock a method that has a predicate argument?

Thanks

like image 318
beijxu Avatar asked Jun 29 '15 15:06

beijxu


1 Answers

I see 4 possible solutions:

  1. Always return the exact same Predicate instance from your isUserValid() method. Since the Predicate is stateless, that's not a problem.

  2. Implement the Predicate as a real class, implementing equals() and hashCode(). But that's overkill compared to the first solution.

  3. Use a matcher:

     Mockito.when(mockObjectA).methodA(Mockito.eq("some id"), Mockito.<Predicate<User>>anyObject()).thenReturn("something");
    
  4. Don't use a static method to create the predicate, but an injectable Factory, that you can mock and verify:

    PredicatesProvider mockPredicatesProvider = mock(PredicatesProvider.class);
    Predicate<User> expectedPredicate = (u -> true);
    when(mockPredicatesProvider.isUserValid()).thenReturn(expectedPredicate);
    when(mockObjectA).methodA("some id", expectedPredicate).thenReturn("something");
    
like image 54
JB Nizet Avatar answered Oct 04 '22 03:10

JB Nizet