/* * Copyright (c) 2016 Mockito contributors * This program is made available under the terms of the MIT License. */ package org.mockito.hamcrest; import org.hamcrest.Matcher; import org.mockito.ArgumentMatcher; import org.mockito.internal.hamcrest.HamcrestArgumentMatcher; import static org.mockito.internal.hamcrest.MatcherGenericTypeExtractor.genericTypeOfMatcher; import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress; import static org.mockito.internal.util.Primitives.defaultValue; /** * Allows matching arguments with hamcrest matchers. * Requires hamcrest on classpath, * Mockito does not depend on hamcrest! * Note the NullPointerException auto-unboxing caveat described below. *

* Before implementing or reusing an existing hamcrest matcher please read * how to deal with sophisticated argument matching in {@link ArgumentMatcher}. *

* Mockito 2.1.0 was decoupled from Hamcrest to avoid version incompatibilities * that have impacted our users in past. Mockito offers a dedicated API to match arguments * via {@link ArgumentMatcher}. * Hamcrest integration is provided so that users can take advantage of existing Hamcrest matchers. *

* Example: *

 *     import static org.mockito.hamcrest.MockitoHamcrest.argThat;
 *
 *     //stubbing
 *     when(mock.giveMe(argThat(new MyHamcrestMatcher())));
 *
 *     //verification
 *     verify(mock).giveMe(argThat(new MyHamcrestMatcher()));
 * 
* NullPointerException auto-unboxing caveat. * In rare cases when matching primitive parameter types you *must* use relevant intThat(), floatThat(), etc. method. * This way you will avoid NullPointerException during auto-unboxing. * Due to how java works we don't really have a clean way of detecting this scenario and protecting the user from this problem. * Hopefully, the javadoc describes the problem and solution well. * If you have an idea how to fix the problem, let us know via the mailing list or the issue tracker. * * @since 2.1.0 */ public class MockitoHamcrest { /** * Allows matching arguments with hamcrest matchers. *

* See examples in javadoc for {@link MockitoHamcrest} class * * @param matcher decides whether argument matches * @return null or default value for primitive (0, false, etc.) * @since 2.1.0 */ @SuppressWarnings("unchecked") public static T argThat(Matcher matcher) { reportMatcher(matcher); return (T) defaultValue(genericTypeOfMatcher(matcher.getClass())); } /** * Enables integrating hamcrest matchers that match primitive char arguments. * Note that {@link #argThat} will not work with primitive char matchers due to NullPointerException auto-unboxing caveat. *

* See examples in javadoc for {@link MockitoHamcrest} class * * @param matcher decides whether argument matches * @return 0. */ public static char charThat(Matcher matcher) { reportMatcher(matcher); return 0; } /** * Enables integrating hamcrest matchers that match primitive boolean arguments. * Note that {@link #argThat} will not work with primitive boolean matchers due to NullPointerException auto-unboxing caveat. *

* See examples in javadoc for {@link MockitoHamcrest} class * * @param matcher decides whether argument matches * @return false. */ public static boolean booleanThat(Matcher matcher) { reportMatcher(matcher); return false; } /** * Enables integrating hamcrest matchers that match primitive byte arguments. * Note that {@link #argThat} will not work with primitive byte matchers due to NullPointerException auto-unboxing caveat. *

* * See examples in javadoc for {@link MockitoHamcrest} class * * @param matcher decides whether argument matches * @return 0. */ public static byte byteThat(Matcher matcher) { reportMatcher(matcher); return 0; } /** * Enables integrating hamcrest matchers that match primitive short arguments. * Note that {@link #argThat} will not work with primitive short matchers due to NullPointerException auto-unboxing caveat. *

* * See examples in javadoc for {@link MockitoHamcrest} class * * @param matcher decides whether argument matches * @return 0. */ public static short shortThat(Matcher matcher) { reportMatcher(matcher); return 0; } /** * Enables integrating hamcrest matchers that match primitive int arguments. * Note that {@link #argThat} will not work with primitive int matchers due to NullPointerException auto-unboxing caveat. *

* * See examples in javadoc for {@link MockitoHamcrest} class * * @param matcher decides whether argument matches * @return 0. */ public static int intThat(Matcher matcher) { reportMatcher(matcher); return 0; } /** * Enables integrating hamcrest matchers that match primitive long arguments. * Note that {@link #argThat} will not work with primitive long matchers due to NullPointerException auto-unboxing caveat. *

* * See examples in javadoc for {@link MockitoHamcrest} class * * @param matcher decides whether argument matches * @return 0. */ public static long longThat(Matcher matcher) { reportMatcher(matcher); return 0; } /** * Enables integrating hamcrest matchers that match primitive float arguments. * Note that {@link #argThat} will not work with primitive float matchers due to NullPointerException auto-unboxing caveat. *

* * See examples in javadoc for {@link MockitoHamcrest} class * * @param matcher decides whether argument matches * @return 0. */ public static float floatThat(Matcher matcher) { reportMatcher(matcher); return 0; } /** * Enables integrating hamcrest matchers that match primitive double arguments. * Note that {@link #argThat} will not work with primitive double matchers due to NullPointerException auto-unboxing caveat. *

* * See examples in javadoc for {@link MockitoHamcrest} class * * @param matcher decides whether argument matches * @return 0. */ public static double doubleThat(Matcher matcher) { reportMatcher(matcher); return 0; } private static void reportMatcher(Matcher matcher) { mockingProgress().getArgumentMatcherStorage().reportMatcher(new HamcrestArgumentMatcher(matcher)); } }