• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.mockito.internal.verification.checkers;
7 
8 import static java.util.Arrays.asList;
9 import static java.util.Collections.emptyList;
10 import static org.assertj.core.api.Assertions.assertThat;
11 
12 import java.util.List;
13 import org.hamcrest.BaseMatcher;
14 import org.hamcrest.Description;
15 import org.hamcrest.TypeSafeMatcher;
16 import org.junit.Rule;
17 import org.junit.Test;
18 import org.junit.rules.ExpectedException;
19 import org.junit.rules.TestName;
20 import org.junit.runner.RunWith;
21 import org.mockito.Mock;
22 import org.mockito.exceptions.verification.NeverWantedButInvoked;
23 import org.mockito.exceptions.verification.TooLittleActualInvocations;
24 import org.mockito.exceptions.verification.TooManyActualInvocations;
25 import org.mockito.internal.invocation.InvocationBuilder;
26 import org.mockito.internal.invocation.InvocationMatcher;
27 import org.mockito.invocation.Invocation;
28 import org.mockito.junit.MockitoJUnitRunner;
29 import org.mockitousage.IMethods;
30 
31 @RunWith(MockitoJUnitRunner.class)
32 public class NumberOfInvocationsCheckerTest {
33 
34     private InvocationMatcher wanted;
35 
36     private List<Invocation> invocations;
37 
38     @Mock
39     private IMethods mock;
40 
41     @Rule
42     public ExpectedException exception = ExpectedException.none();
43 
44     @Rule
45     public TestName testName = new TestName();
46 
47     @Test
shouldReportTooLittleActual()48     public void shouldReportTooLittleActual() throws Exception {
49         wanted = buildSimpleMethod().toInvocationMatcher();
50         invocations = asList(buildSimpleMethod().toInvocation(), buildSimpleMethod().toInvocation());
51 
52         exception.expect(TooLittleActualInvocations.class);
53         exception.expectMessage("mock.simpleMethod()");
54         exception.expectMessage("Wanted 100 times");
55         exception.expectMessage("But was 2 times");
56 
57         NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 100);
58     }
59 
60     @Test
shouldReportWithLastInvocationStackTrace()61     public void shouldReportWithLastInvocationStackTrace() throws Exception {
62         wanted = buildSimpleMethod().toInvocationMatcher();
63         invocations = asList(buildSimpleMethod().toInvocation(), buildSimpleMethod().toInvocation());
64 
65         exception.expect(TooLittleActualInvocations.class);
66         exception.expectMessage("mock.simpleMethod()");
67         exception.expectMessage("Wanted 100 times");
68         exception.expectMessage("But was 2 times");
69         exception.expectMessage(containsTimes("-> at", 2));
70 
71         NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 100);
72     }
73 
74     @Test
shouldNotReportWithLastInvocationStackTraceIfNoInvocationsFound()75     public void shouldNotReportWithLastInvocationStackTraceIfNoInvocationsFound() throws Exception {
76         invocations = emptyList();
77         wanted = buildSimpleMethod().toInvocationMatcher();
78 
79         exception.expect(TooLittleActualInvocations.class);
80         exception.expectMessage("mock.simpleMethod()");
81         exception.expectMessage("Wanted 100 times");
82         exception.expectMessage("But was 0 times");
83         exception.expectMessage(containsTimes("-> at", 1));
84 
85         NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 100);
86     }
87 
88     @Test
shouldReportWithFirstUndesiredInvocationStackTrace()89     public void shouldReportWithFirstUndesiredInvocationStackTrace() throws Exception {
90         Invocation first = buildSimpleMethod().toInvocation();
91         Invocation second = buildSimpleMethod().toInvocation();
92         Invocation third = buildSimpleMethod().toInvocation();
93 
94         invocations = asList(first, second, third);
95         wanted = buildSimpleMethod().toInvocationMatcher();
96 
97         exception.expect(TooManyActualInvocations.class);
98         exception.expectMessage("" + third.getLocation());
99         NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 2);
100     }
101 
102     @Test
shouldReportTooManyActual()103     public void shouldReportTooManyActual() throws Exception {
104         Invocation first = buildSimpleMethod().toInvocation();
105         Invocation second = buildSimpleMethod().toInvocation();
106 
107         invocations = asList(first, second);
108         wanted = buildSimpleMethod().toInvocationMatcher();
109 
110         exception.expectMessage("Wanted 1 time");
111         exception.expectMessage("But was 2 times");
112 
113         NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 1);
114     }
115 
116     @Test
shouldReportNeverWantedButInvoked()117     public void shouldReportNeverWantedButInvoked() throws Exception {
118         Invocation first = buildSimpleMethod().toInvocation();
119 
120         invocations = asList(first);
121         wanted = buildSimpleMethod().toInvocationMatcher();
122 
123         exception.expect(NeverWantedButInvoked.class);
124         exception.expectMessage("Never wanted here");
125         exception.expectMessage("But invoked here");
126         exception.expectMessage("" + first.getLocation());
127 
128         NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 0);
129     }
130 
131 	@Test
shouldMarkInvocationsAsVerified()132 	public void shouldMarkInvocationsAsVerified() throws Exception {
133 		Invocation invocation = buildSimpleMethod().toInvocation();
134 		assertThat(invocation.isVerified()).isFalse();
135 
136 		invocations = asList(invocation);
137 		wanted = buildSimpleMethod().toInvocationMatcher();
138 		NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 1);
139 		assertThat(invocation.isVerified()).isTrue();
140 	}
141 
buildSimpleMethod()142     private InvocationBuilder buildSimpleMethod() {
143         return new InvocationBuilder().mock(mock).simpleMethod();
144     }
145 
containsTimes(String value, int amount)146     private static BaseMatcher<String> containsTimes(String value, int amount) {
147         return new StringContainsNumberMatcher(value, amount);
148     }
149 
150     private static class StringContainsNumberMatcher extends TypeSafeMatcher<String> {
151 
152         private final String expected;
153 
154         private final int amount;
155 
StringContainsNumberMatcher(String expected, int amount)156         StringContainsNumberMatcher(String expected, int amount) {
157             this.expected = expected;
158             this.amount = amount;
159         }
160 
matchesSafely(String text)161         public boolean matchesSafely(String text) {
162             int lastIndex = 0;
163             int count = 0;
164             while (lastIndex != -1) {
165                 lastIndex = text.indexOf(expected, lastIndex);
166                 if (lastIndex != -1) {
167                     count++;
168                     lastIndex += expected.length();
169                 }
170             }
171             return count == amount;
172         }
173 
describeTo(Description description)174         public void describeTo(Description description) {
175             description.appendText("containing '" + expected + "' exactly " + amount + " times");
176         }
177 
178     }
179 }
180