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