1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockitousage.matchers; 6 7 import static org.assertj.core.api.Assertions.assertThat; 8 import static org.junit.Assert.assertEquals; 9 import static org.junit.Assert.fail; 10 import static org.mockito.ArgumentMatchers.*; 11 import static org.mockito.Mockito.verify; 12 import static org.mockito.Mockito.when; 13 14 import org.junit.Before; 15 import org.junit.Test; 16 import org.mockito.ArgumentMatcher; 17 import org.mockito.Mockito; 18 import org.mockitousage.IMethods; 19 import org.mockitoutil.TestBase; 20 21 public class CustomMatchersTest extends TestBase { 22 23 private final class ContainsFoo implements ArgumentMatcher<String> { matches(String arg)24 public boolean matches(String arg) { 25 return arg.contains("foo"); 26 } 27 } 28 29 private final class IsAnyBoolean implements ArgumentMatcher<Boolean> { matches(Boolean arg)30 public boolean matches(Boolean arg) { 31 return true; 32 } 33 } 34 35 private final class IsSorZ implements ArgumentMatcher<Character> { matches(Character character)36 public boolean matches(Character character) { 37 return character.equals('s') || character.equals('z'); 38 } 39 } 40 41 private final class IsZeroOrOne<T extends Number> implements ArgumentMatcher<T> { matches(T number)42 public boolean matches(T number) { 43 return number.intValue() == 0 || number.intValue() == 1; 44 } 45 } 46 47 private IMethods mock; 48 49 @Before setUp()50 public void setUp() { 51 mock = Mockito.mock(IMethods.class); 52 } 53 54 @Test shouldUseCustomBooleanMatcher()55 public void shouldUseCustomBooleanMatcher() { 56 when(mock.oneArg(booleanThat(new IsAnyBoolean()))).thenReturn("foo"); 57 58 assertEquals("foo", mock.oneArg(true)); 59 assertEquals("foo", mock.oneArg(false)); 60 61 assertEquals(null, mock.oneArg("x")); 62 } 63 64 @Test shouldUseCustomCharMatcher()65 public void shouldUseCustomCharMatcher() { 66 when(mock.oneArg(charThat(new IsSorZ()))).thenReturn("foo"); 67 68 assertEquals("foo", mock.oneArg('s')); 69 assertEquals("foo", mock.oneArg('z')); 70 assertEquals(null, mock.oneArg('x')); 71 } 72 73 class Article { 74 75 private int pageNumber; 76 private String headline; 77 Article(int pageNumber, String headline)78 public Article(int pageNumber, String headline) { 79 super(); 80 this.pageNumber = pageNumber; 81 this.headline = headline; 82 } 83 getPageNumber()84 public int getPageNumber() { 85 return pageNumber; 86 } 87 getHeadline()88 public String getHeadline() { 89 return headline; 90 } 91 } 92 93 @Test shouldUseCustomPrimitiveNumberMatchers()94 public void shouldUseCustomPrimitiveNumberMatchers() { 95 when(mock.oneArg(byteThat(new IsZeroOrOne<Byte>()))).thenReturn("byte"); 96 when(mock.oneArg(shortThat(new IsZeroOrOne<Short>()))).thenReturn("short"); 97 when(mock.oneArg(intThat(new IsZeroOrOne<Integer>()))).thenReturn("int"); 98 when(mock.oneArg(longThat(new IsZeroOrOne<Long>()))).thenReturn("long"); 99 when(mock.oneArg(floatThat(new IsZeroOrOne<Float>()))).thenReturn("float"); 100 when(mock.oneArg(doubleThat(new IsZeroOrOne<Double>()))).thenReturn("double"); 101 102 assertEquals("byte", mock.oneArg((byte) 0)); 103 assertEquals("short", mock.oneArg((short) 1)); 104 assertEquals("int", mock.oneArg(0)); 105 assertEquals("long", mock.oneArg(1L)); 106 assertEquals("float", mock.oneArg(0F)); 107 assertEquals("double", mock.oneArg(1.0)); 108 109 assertEquals(null, mock.oneArg(2)); 110 assertEquals(null, mock.oneArg("foo")); 111 } 112 113 @Test shouldUseCustomObjectMatcher()114 public void shouldUseCustomObjectMatcher() { 115 when(mock.oneArg(argThat(new ContainsFoo()))).thenReturn("foo"); 116 117 assertEquals("foo", mock.oneArg("foo")); 118 assertEquals(null, mock.oneArg("bar")); 119 } 120 121 @Test shouldCustomMatcherPrintDescriptionBasedOnName()122 public void shouldCustomMatcherPrintDescriptionBasedOnName() { 123 mock.simpleMethod("foo"); 124 125 try { 126 verify(mock).simpleMethod(containsTest()); 127 fail(); 128 } catch (AssertionError e) { 129 assertThat(e).hasMessageContaining("<String that contains xxx>"); 130 } 131 } 132 containsTest()133 private String containsTest() { 134 return argThat(new StringThatContainsXxx()); 135 } 136 137 private final class StringThatContainsXxx implements ArgumentMatcher<String> { matches(String arg)138 public boolean matches(String arg) { 139 return arg.contains("xxx"); 140 } 141 } 142 143 @Test shouldAnonymousCustomMatcherPrintDefaultDescription()144 public void shouldAnonymousCustomMatcherPrintDefaultDescription() { 145 mock.simpleMethod("foo"); 146 147 try { 148 verify(mock) 149 .simpleMethod( 150 (String) 151 argThat( 152 new ArgumentMatcher<Object>() { 153 public boolean matches(Object argument) { 154 return false; 155 } 156 })); 157 fail(); 158 } catch (AssertionError e) { 159 assertThat(e) 160 .hasMessageContaining("<custom argument matcher>") 161 .hasMessageContaining("foo"); 162 } 163 } 164 } 165