• 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 java.util.List;
9 import org.hamcrest.BaseMatcher;
10 import org.hamcrest.Description;
11 import org.hamcrest.TypeSafeMatcher;
12 import org.junit.Rule;
13 import org.junit.Test;
14 import org.junit.rules.ExpectedException;
15 import org.junit.rules.TestName;
16 import org.junit.runner.RunWith;
17 import org.mockito.Mock;
18 import org.mockito.exceptions.verification.NeverWantedButInvoked;
19 import org.mockito.exceptions.verification.TooLittleActualInvocations;
20 import org.mockito.exceptions.verification.TooManyActualInvocations;
21 import org.mockito.internal.invocation.InvocationBuilder;
22 import org.mockito.internal.invocation.InvocationMatcher;
23 import org.mockito.invocation.Invocation;
24 import org.mockito.junit.MockitoJUnitRunner;
25 import org.mockitousage.IMethods;
26 
27 import static java.util.Arrays.asList;
28 import static java.util.Collections.emptyList;
29 import static org.assertj.core.api.Assertions.assertThat;
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
shouldReportAllInvocationsStackTrace()61     public void shouldReportAllInvocationsStackTrace() 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", 3));
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
shouldReportWithAllInvocationsStackTrace()89     public void shouldReportWithAllInvocationsStackTrace() 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("" + first.getLocation());
99         exception.expectMessage("" + second.getLocation());
100         exception.expectMessage("" + third.getLocation());
101         NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 2);
102     }
103 
104     @Test
shouldReportTooManyActual()105     public void shouldReportTooManyActual() throws Exception {
106         Invocation first = buildSimpleMethod().toInvocation();
107         Invocation second = buildSimpleMethod().toInvocation();
108 
109         invocations = asList(first, second);
110         wanted = buildSimpleMethod().toInvocationMatcher();
111 
112         exception.expectMessage("Wanted 1 time");
113         exception.expectMessage("But was 2 times");
114 
115         NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 1);
116     }
117 
118     @Test
shouldReportNeverWantedButInvoked()119     public void shouldReportNeverWantedButInvoked() throws Exception {
120         Invocation first = buildSimpleMethod().toInvocation();
121 
122         invocations = asList(first);
123         wanted = buildSimpleMethod().toInvocationMatcher();
124 
125         exception.expect(NeverWantedButInvoked.class);
126         exception.expectMessage("Never wanted here");
127         exception.expectMessage("But invoked here");
128         exception.expectMessage("" + first.getLocation());
129 
130         NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 0);
131     }
132 
133 	@Test
shouldMarkInvocationsAsVerified()134 	public void shouldMarkInvocationsAsVerified() throws Exception {
135 		Invocation invocation = buildSimpleMethod().toInvocation();
136 		assertThat(invocation.isVerified()).isFalse();
137 
138 		invocations = asList(invocation);
139 		wanted = buildSimpleMethod().toInvocationMatcher();
140 		NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 1);
141 		assertThat(invocation.isVerified()).isTrue();
142 	}
143 
buildSimpleMethod()144     private InvocationBuilder buildSimpleMethod() {
145         return new InvocationBuilder().mock(mock).simpleMethod();
146     }
147 
containsTimes(String value, int amount)148     private static BaseMatcher<String> containsTimes(String value, int amount) {
149         return new StringContainsNumberMatcher(value, amount);
150     }
151 
152     private static class StringContainsNumberMatcher extends TypeSafeMatcher<String> {
153 
154         private final String expected;
155 
156         private final int amount;
157 
StringContainsNumberMatcher(String expected, int amount)158         StringContainsNumberMatcher(String expected, int amount) {
159             this.expected = expected;
160             this.amount = amount;
161         }
162 
matchesSafely(String text)163         public boolean matchesSafely(String text) {
164             int lastIndex = 0;
165             int count = 0;
166             while (lastIndex != -1) {
167                 lastIndex = text.indexOf(expected, lastIndex);
168                 if (lastIndex != -1) {
169                     count++;
170                     lastIndex += expected.length();
171                 }
172             }
173             return count == amount;
174         }
175 
describeTo(Description description)176         public void describeTo(Description description) {
177             description.appendText("containing '" + expected + "' exactly " + amount + " times");
178         }
179 
180     }
181 }
182