All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fitbur.mockito.ArgumentMatcher Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
package com.fitbur.mockito;

/**
 * Allows creating customized argument matchers.
 * This API was changed in Mockito 2.* in an effort to decouple Mockito from Hamcrest
 * and reduce the risk of version incompatibility.
 * Migration guide is included close to the bottom of this javadoc.
 * 

* For non-trivial method arguments used in stubbing or verification, you have following options * (in no particular order): *

    *
  • refactor the code so that the interactions with collaborators are easier to test with mocks. * Perhaps it is possible to pass a different argument to the method so that mocking is easier? * If stuff is hard to test it usually indicates the design could be better, so do refactor for testability! *
  • *
  • don't match the argument strictly, just use one of the lenient argument matchers like * {@link Mockito#notNull()}. Some times it is better to have a simple test that works than * a complicated test that seem to work. *
  • *
  • implement equals() method in the objects that are used as arguments to mocks. * Mockito naturally uses equals() for argument matching. * Many times, this is option is clean and simple. *
  • *
  • use {@link ArgumentCaptor} to capture the arguments and perform assertions on their state. * Useful when you need to verify the arguments. Captor is not useful if you need argument matching for stubbing. * Many times, this option leads to clean and readable tests with fine-grained validation of arguments. *
  • *
  • use customized argument matchers by implementing {@link ArgumentMatcher} interface * and passing the implementation to the {@link Mockito#argThat} method. * This option is useful if custom matcher is needed for stubbing and can be reused a lot. * Note that {@link Mockito#argThat} demonstrates NullPointerException auto-unboxing caveat. *
  • *
  • use an instance of hamcrest matcher and pass it to * {@link com.fitbur.mockito.hamcrest.MockitoHamcrest#argThat(org.hamcrest.Matcher)} * Useful if you already have a hamcrest matcher. Reuse and win! * Note that {@link com.fitbur.mockito.hamcrest.MockitoHamcrest#argThat(org.hamcrest.Matcher)} demonstrates NullPointerException auto-unboxing caveat. *
  • *
  • Java 8 only - use a lambda in place of an {@link ArgumentMatcher} since {@link ArgumentMatcher} * is effectively a functional interface. A lambda can be used with the {@link Mockito#argThat} method.
  • *
* *

* Implementations of this interface can be used with {@link Matchers#argThat} method. * Use toString() method for description of the matcher * - it is printed in verification errors. * *


 * class ListOfTwoElements implements ArgumentMatcher<List> {
 *     public boolean matches(List list) {
 *         return list.size() == 2;
 *     }
 *     public String toString() {
 *         //printed in verification errors
 *         return "[list of 2 elements]";
 *     }
 * }
 *
 * List mock = mock(List.class);
 *
 * when(mock.addAll(argThat(new ListOfTwoElements))).thenReturn(true);
 *
 * mock.addAll(Arrays.asList("one", "two"));
 *
 * verify(mock).addAll(argThat(new ListOfTwoElements()));
 * 
* * To keep it readable you can extract method, e.g: * *

 *   verify(mock).addAll(argThat(new ListOfTwoElements()));
 *   //becomes
 *   verify(mock).addAll(listOfTwoElements());
 * 
* * In Java 8 you can treat ArgumentMatcher as a functional interface * and use a lambda, e.g.: * *

 *   verify(mock).addAll(argThat(list -> list.size() == 2));
 * 
* *

* Read more about other matchers in javadoc for {@link Matchers} class. *

2.0 migration guide

* * All existing custom implementations of ArgumentMatcher will no longer compile. * All locations where hamcrest matchers are passed to argThat() will no longer compile. * There are 2 approaches to fix the problems: *
    *
  • a) Refactor the hamcrest matcher to Mockito matcher: * Use "implements ArgumentMatcher" instead of "extends ArgumentMatcher". * Then refactor describeTo() method into toString() method. *
  • *
  • * b) Use com.fitbur.mockito.hamcrest.MockitoHamcrest.argThat() instead of Mockito.argThat(). * Ensure that there is hamcrest dependency on classpath * (Mockito does not depend on hamcrest any more). * *
  • *
* What option is right for you? If you don't mind compile dependency to hamcrest * then option b) is probably right for you. * Your choice should not have big impact and is fully reversible - * you can choose different option in future (and refactor the code) * * @param type of argument * @since 2.0 */ public interface ArgumentMatcher { /** * Informs if this matcher accepts the given argument. *

* The method should never assert if the argument doesn't match. It * should only return false. *

* See the example in the top level javadoc for {@link ArgumentMatcher} * * @param argument * the argument * @return true if this matcher accepts the given argument. */ boolean matches(T argument); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy