17 | * With Java 8 and lambda expressions ArgumentCaptor can be inlined: 18 | * 19 | *
20 | * {@literal @}Test
21 | * public void shouldAllowToUseAssertionInLambda() {
22 | * //when
23 | * ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
24 | * //then
25 | * verify(ts).findNumberOfShipsInRangeByCriteria(assertArg(sc -> assertThat(sc.getMinimumRange()).isLessThan(2000)));
26 | * }
27 | *
28 | *
29 | * in comparison to 3 lines in the classic way:
30 | *
31 | *
32 | * {@literal @}Test
33 | * public void shouldAllowToUseArgumentCaptorInClassicWay() { //old way
34 | * //when
35 | * ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
36 | * //then
37 | * ArgumentCaptor captor = ArgumentCaptor.forClass(ShipSearchCriteria.class);
38 | * verify(ts).findNumberOfShipsInRangeByCriteria(captor.capture());
39 | * assertThat(captor.getValue().getMinimumRange()).isLessThan(2000);
40 | * }
41 | *
42 | * AssertJ assertions (assertThat()) used in lambda generate meaningful error messages in face of failure, but any other assertion can be
43 | * used if needed/preferred.
44 | *
45 | * @param type of argument
46 | *
47 | * @author Marcin Zajączkowski
48 | */
49 | @SuppressWarnings("WeakerAccess")
50 | public class AssertionMatcher implements ArgumentMatcher {
51 |
52 | private static final LambdaAwareHandyReturnValues handyReturnValues = new LambdaAwareHandyReturnValues();
53 |
54 | private final Consumer consumer;
55 | private String errorMessage;
56 |
57 | private AssertionMatcher(Consumer consumer) {
58 | this.consumer = consumer;
59 | }
60 |
61 | @SuppressWarnings("unchecked")
62 | @Override
63 | public boolean matches(T argument) {
64 | try {
65 | consumer.accept(argument);
66 | return true;
67 | } catch (AssertionError e) {
68 | errorMessage = e.getMessage();
69 | return false;
70 | }
71 | }
72 |
73 | @Override
74 | public String toString() {
75 | return "AssertionMatcher reported: " + errorMessage;
76 | }
77 |
78 | public static T assertArg(Consumer consumer) {
79 | argThat(consumer);
80 | return handyReturnValues.returnForConsumerLambda(consumer);
81 | }
82 |
83 | /**
84 | * A variant of assertArg(Consumer) for lambdas declaring checked exceptions.
85 | */
86 | @Incubating
87 | public static T assertArgThrowing(ThrowingConsumer throwingConsumer) {
88 | argThat(throwingConsumer.uncheck());
89 | return handyReturnValues.returnForConsumerLambdaChecked(throwingConsumer);
90 | }
91 |
92 | @SuppressWarnings("ResultOfMethodCallIgnored")
93 | private static void argThat(Consumer consumer) {
94 | Mockito.argThat(new AssertionMatcher<>(consumer));
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/info/solidsoft/mockito/java8/LambdaAwareHandyReturnValues.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Marcin Zajączkowski.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8;
7 |
8 | import net.jodah.typetools.TypeResolver;
9 | import org.mockito.internal.util.Primitives;
10 |
11 | import java.util.function.Consumer;
12 |
13 | /**
14 | * Extended version of HandyReturnValues which can resolve safe return type also for Consumer argument.
15 | *
16 | * Under the hood it uses TypeTools library which is used to work also for primitive argument types (to not throw NullPointerException).
17 | *
18 | * @author Marcin Zajączkowski
19 | */
20 | class LambdaAwareHandyReturnValues {
21 |
22 | T returnForConsumerLambda(Consumer consumer) {
23 | return internalReturnForLambda(consumer, Consumer.class);
24 | }
25 |
26 | T returnForConsumerLambdaChecked(ThrowingConsumer throwingConsumer) {
27 | return internalReturnForLambda(throwingConsumer, ThrowingConsumer.class);
28 | }
29 |
30 | @SuppressWarnings("unchecked")
31 | private T internalReturnForLambda(Object consumer, Class consumerType) {
32 | Class>[] typeArgs = TypeResolver.resolveRawArguments(consumerType, consumer.getClass());
33 | return (T) Primitives.defaultValue(typeArgs[0]);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/info/solidsoft/mockito/java8/LambdaMatcher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Marcin Zajączkowski.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8;
7 |
8 | import org.mockito.ArgumentMatcher;
9 | import org.mockito.Incubating;
10 |
11 | import java.util.function.Predicate;
12 |
13 | import static org.mockito.ArgumentMatchers.argThat;
14 |
15 | /**
16 | * Allows creating inlined argument matcher with a lambda expression.
17 | *
18 | * With Java 8 and lambda expressions ArgumentCaptor can be expressed inline:
19 | *
20 | *
21 | *{@literal @}Test
22 | * public void shouldAllowToUseLambdaInStubbing() {
23 | * //given
24 | * given(ts.findNumberOfShipsInRangeByCriteria(argLambda(c -> c.getMinimumRange() > 1000))).willReturn(4);
25 | * //expect
26 | * assertThat(ts.findNumberOfShipsInRangeByCriteria(new ShipSearchCriteria(1500, 2))).isEqualTo(4);
27 | * //expect
28 | * assertThat(ts.findNumberOfShipsInRangeByCriteria(new ShipSearchCriteria(700, 2))).isEqualTo(0);
29 | * }
30 | *
31 | *
32 | * In comparison the same logic implemented with a custom Answer in Java 7:
33 | *
34 | *
35 | *{@literal @}Test
36 | * public void stubbingWithCustomAnswerShouldBeLonger() { //old way
37 | * //given
38 | * given(ts.findNumberOfShipsInRangeByCriteria(any())).willAnswer(new Answer() {
39 | * {@literal @}Override
40 | * public Integer answer(InvocationOnMock invocation) throws Throwable {
41 | * Object[] args = invocation.getArguments();
42 | * ShipSearchCriteria criteria = (ShipSearchCriteria) args[0];
43 | * if (criteria.getMinimumRange() > 1000) {
44 | * return 4;
45 | * } else {
46 | * return 0;
47 | * }
48 | * }
49 | * });
50 | * //expect
51 | * assertThat(ts.findNumberOfShipsInRangeByCriteria(new ShipSearchCriteria(1500, 2))).isEqualTo(4);
52 | * //expect
53 | * assertThat(ts.findNumberOfShipsInRangeByCriteria(new ShipSearchCriteria(700, 2))).isEqualTo(0);
54 | * }
55 | *
56 | *
57 | * Even Java 8 alone and using less readable constructions produce less compact code:
58 | *
59 | *
60 | *{@literal @}Test
61 | * public void stubbingWithCustomAsnwerShouldBeLongerEvenAsLambda() { //old way
62 | * //given
63 | * given(ts.findNumberOfShipsInRangeByCriteria(any())).willAnswer(invocation -> {
64 | * ShipSearchCriteria criteria = (ShipSearchCriteria) invocation.getArguments()[0];
65 | * return criteria.getMinimumRange() > 1000 ? 4 : 0;
66 | * });
67 | * //expect
68 | * assertThat(ts.findNumberOfShipsInRangeByCriteria(new ShipSearchCriteria(1500, 2))).isEqualTo(4);
69 | * //expect
70 | * assertThat(ts.findNumberOfShipsInRangeByCriteria(new ShipSearchCriteria(700, 2))).isEqualTo(0);
71 | * }
72 | *
73 | *
74 | * @param type of argument
75 | *
76 | * @author Marcin Zajączkowski
77 | */
78 | @SuppressWarnings("WeakerAccess")
79 | public class LambdaMatcher implements ArgumentMatcher {
80 |
81 | private final ArgumentMatcher backendMatcher; //TODO: Could it be done with just one matcher?
82 |
83 | private LambdaMatcher(Predicate lambda, String description) {
84 | this.backendMatcher = new ArgumentMatcher() {
85 | @Override
86 | public boolean matches(T item) {
87 | try {
88 | return lambda.test(item);
89 | } catch (Exception e) {
90 | throw new RuntimeException(e); //Could be potentially tricked with CheckedPredicate.uncheck(), but kept for backward compatibility
91 | }
92 | }
93 |
94 | @Override
95 | public String toString() {
96 | return description;
97 | }
98 | };
99 | }
100 |
101 | @Override
102 | public boolean matches(T item) {
103 | return backendMatcher.matches(item);
104 | }
105 |
106 | @Override
107 | public String toString() {
108 | return backendMatcher.toString();
109 | }
110 |
111 | public static T argLambda(Predicate lambda) {
112 | return argLambda(lambda, "Inline lambda expression - add description in code to get more detailed error message");
113 | }
114 |
115 | public static T argLambda(Predicate lambda, String description) {
116 | return argThat(new LambdaMatcher<>(lambda, description));
117 | }
118 |
119 | /**
120 | * A variant of argLambda(Predicate) for lambdas declaring checked ecceptions.
121 | */
122 | @Incubating
123 | public static T argLambdaThrowing(ThrowingPredicate throwingLambda) {
124 | return argLambda(throwingLambda.uncheck(), "Inline lambda expression - add description in code to get more detailed error message");
125 | }
126 |
127 | /**
128 | * A variant of argLambda(Predicate) for lambdas declaring checked exceptions.
129 | */
130 | @Incubating
131 | public static T argLambdaThrowing(ThrowingPredicate throwingLambda, String description) {
132 | return argThat(new LambdaMatcher<>(throwingLambda.uncheck(), description));
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/main/java/info/solidsoft/mockito/java8/SneakyThrow.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Mockito contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8;
7 |
8 | /**
9 | * An internal class providing a hack to trick the compiler to accept a lack of a declaration of checked exception in a caller.
10 | *
11 | * Based on the idea presented by Grzegorz Piwowarek in his presentation: The Dark Side of Java 8.
12 | * https://4comprehension.com/sneakily-throwing-exceptions-in-lambda-expressions-in-java/
13 | */
14 | class SneakyThrow {
15 |
16 | @SuppressWarnings("unchecked")
17 | static R sneakyRethrow(Exception e) throws E {
18 | throw (E) e;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/info/solidsoft/mockito/java8/ThrowingConsumer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Mockito contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8;
7 |
8 | import org.mockito.Incubating;
9 |
10 | import java.util.function.Consumer;
11 |
12 | import static info.solidsoft.mockito.java8.SneakyThrow.sneakyRethrow;
13 |
14 | @FunctionalInterface
15 | @Incubating
16 | public interface ThrowingConsumer {
17 |
18 | void accept(T t) throws Exception;
19 |
20 | default Consumer uncheck() {
21 | return t -> {
22 | try {
23 | this.accept(t);
24 | } catch (Exception e) {
25 | sneakyRethrow(e);
26 | }
27 | };
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/info/solidsoft/mockito/java8/ThrowingPredicate.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Mockito contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8;
7 |
8 | import org.mockito.Incubating;
9 |
10 | import java.util.function.Predicate;
11 |
12 | import static info.solidsoft.mockito.java8.SneakyThrow.sneakyRethrow;
13 |
14 | @FunctionalInterface
15 | @Incubating
16 | public interface ThrowingPredicate {
17 |
18 | boolean test(T t) throws Exception;
19 |
20 | default Predicate uncheck() {
21 | return t -> {
22 | try {
23 | return this.test(t);
24 | } catch (Exception e) {
25 | return sneakyRethrow(e);
26 | }
27 | };
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/info/solidsoft/mockito/java8/api/WithAdditionalMatchers.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Mockito contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8.api;
7 |
8 | import org.mockito.AdditionalMatchers;
9 | import org.mockito.Incubating;
10 |
11 | /**
12 | * An entry point to Mockito additional matchers.
13 | *
14 | * Created as an alternative approach to static imports. A test class can implement that interface to make methods from
15 | * {@link AdditionalMatchers} class directly available.
16 | *
17 | * Should be used with {@link WithBDDMockito} or {@link WithMockito}.
18 | *
19 | * @see WithBDDMockito
20 | * @see WithMockito
21 | *
22 | * @author Marcin Zajączkowski
23 | * @since 1.0.0
24 | */
25 | @Incubating
26 | public interface WithAdditionalMatchers {
27 |
28 | /**
29 | * Delegates call to {@link AdditionalMatchers#geq(Comparable)}.
30 | */
31 | default > T geq(T value) {
32 | return AdditionalMatchers.geq(value);
33 | }
34 |
35 | /**
36 | * Delegates call to {@link AdditionalMatchers#geq(byte)}.
37 | */
38 | default byte geq(byte value) {
39 | return AdditionalMatchers.geq(value);
40 | }
41 |
42 | /**
43 | * Delegates call to {@link AdditionalMatchers#geq(double)}.
44 | */
45 | default double geq(double value) {
46 | return AdditionalMatchers.geq(value);
47 | }
48 |
49 | /**
50 | * Delegates call to {@link AdditionalMatchers#geq(float)}.
51 | */
52 | default float geq(float value) {
53 | return AdditionalMatchers.geq(value);
54 | }
55 |
56 | /**
57 | * Delegates call to {@link AdditionalMatchers#geq(int)}.
58 | */
59 | default int geq(int value) {
60 | return AdditionalMatchers.geq(value);
61 | }
62 |
63 | /**
64 | * Delegates call to {@link AdditionalMatchers#geq(long)}.
65 | */
66 | default long geq(long value) {
67 | return AdditionalMatchers.geq(value);
68 | }
69 |
70 | /**
71 | * Delegates call to {@link AdditionalMatchers#geq(short)}.
72 | */
73 | default short geq(short value) {
74 | return AdditionalMatchers.geq(value);
75 | }
76 |
77 | /**
78 | * Delegates call to {@link AdditionalMatchers#leq(Comparable)}.
79 | */
80 | default > T leq(T value) {
81 | return AdditionalMatchers.leq(value);
82 | }
83 |
84 | /**
85 | * Delegates call to {@link AdditionalMatchers#leq(byte)}.
86 | */
87 | default byte leq(byte value) {
88 | return AdditionalMatchers.leq(value);
89 | }
90 |
91 | /**
92 | * Delegates call to {@link AdditionalMatchers#leq(double)}.
93 | */
94 | default double leq(double value) {
95 | return AdditionalMatchers.leq(value);
96 | }
97 |
98 | /**
99 | * Delegates call to {@link AdditionalMatchers#leq(float)}.
100 | */
101 | default float leq(float value) {
102 | return AdditionalMatchers.leq(value);
103 | }
104 |
105 | /**
106 | * Delegates call to {@link AdditionalMatchers#leq(int)}.
107 | */
108 | default int leq(int value) {
109 | return AdditionalMatchers.leq(value);
110 | }
111 |
112 | /**
113 | * Delegates call to {@link AdditionalMatchers#leq(long)}.
114 | */
115 | default long leq(long value) {
116 | return AdditionalMatchers.leq(value);
117 | }
118 |
119 | /**
120 | * Delegates call to {@link AdditionalMatchers#leq(short)}.
121 | */
122 | default short leq(short value) {
123 | return AdditionalMatchers.leq(value);
124 | }
125 |
126 | /**
127 | * Delegates call to {@link AdditionalMatchers#gt(Comparable)}.
128 | */
129 | default > T gt(T value) {
130 | return AdditionalMatchers.gt(value);
131 | }
132 |
133 | /**
134 | * Delegates call to {@link AdditionalMatchers#gt(byte)}.
135 | */
136 | default byte gt(byte value) {
137 | return AdditionalMatchers.gt(value);
138 | }
139 |
140 | /**
141 | * Delegates call to {@link AdditionalMatchers#gt(double)}.
142 | */
143 | default double gt(double value) {
144 | return AdditionalMatchers.gt(value);
145 | }
146 |
147 | /**
148 | * Delegates call to {@link AdditionalMatchers#gt(float)}.
149 | */
150 | default float gt(float value) {
151 | return AdditionalMatchers.gt(value);
152 | }
153 |
154 | /**
155 | * Delegates call to {@link AdditionalMatchers#gt(int)}.
156 | */
157 | default int gt(int value) {
158 | return AdditionalMatchers.gt(value);
159 | }
160 |
161 | /**
162 | * Delegates call to {@link AdditionalMatchers#gt(long)}.
163 | */
164 | default long gt(long value) {
165 | return AdditionalMatchers.gt(value);
166 | }
167 |
168 | /**
169 | * Delegates call to {@link AdditionalMatchers#gt(short)}.
170 | */
171 | default short gt(short value) {
172 | return AdditionalMatchers.gt(value);
173 | }
174 |
175 | /**
176 | * Delegates call to {@link AdditionalMatchers#lt(Comparable)}.
177 | */
178 | default > T lt(T value) {
179 | return AdditionalMatchers.lt(value);
180 | }
181 |
182 | /**
183 | * Delegates call to {@link AdditionalMatchers#lt(byte)}.
184 | */
185 | default byte lt(byte value) {
186 | return AdditionalMatchers.lt(value);
187 | }
188 |
189 | /**
190 | * Delegates call to {@link AdditionalMatchers#lt(double)}.
191 | */
192 | default double lt(double value) {
193 | return AdditionalMatchers.lt(value);
194 | }
195 |
196 | /**
197 | * Delegates call to {@link AdditionalMatchers#lt(float)}.
198 | */
199 | default float lt(float value) {
200 | return AdditionalMatchers.lt(value);
201 | }
202 |
203 | /**
204 | * Delegates call to {@link AdditionalMatchers#lt(int)}.
205 | */
206 | default int lt(int value) {
207 | return AdditionalMatchers.lt(value);
208 | }
209 |
210 | /**
211 | * Delegates call to {@link AdditionalMatchers#lt(long)}.
212 | */
213 | default long lt(long value) {
214 | return AdditionalMatchers.lt(value);
215 | }
216 |
217 | /**
218 | * Delegates call to {@link AdditionalMatchers#lt(short)}.
219 | */
220 | default short lt(short value) {
221 | return AdditionalMatchers.lt(value);
222 | }
223 |
224 | /**
225 | * Delegates call to {@link AdditionalMatchers#cmpEq(Comparable)}.
226 | */
227 | default > T cmpEq(T value) {
228 | return AdditionalMatchers.cmpEq(value);
229 | }
230 |
231 | /**
232 | * Delegates call to {@link AdditionalMatchers#find(String)}.
233 | */
234 | default String find(String regex) {
235 | return AdditionalMatchers.find(regex);
236 | }
237 |
238 | /**
239 | * Delegates call to {@link AdditionalMatchers#aryEq(T[])}.
240 | */
241 | default T[] aryEq(T[] value) {
242 | return AdditionalMatchers.aryEq(value);
243 | }
244 |
245 | /**
246 | * Delegates call to {@link AdditionalMatchers#aryEq(short[])}.
247 | */
248 | default short[] aryEq(short[] value) {
249 | return AdditionalMatchers.aryEq(value);
250 | }
251 |
252 | /**
253 | * Delegates call to {@link AdditionalMatchers#aryEq(long[])}.
254 | */
255 | default long[] aryEq(long[] value) {
256 | return AdditionalMatchers.aryEq(value);
257 | }
258 |
259 | /**
260 | * Delegates call to {@link AdditionalMatchers#aryEq(int[])}.
261 | */
262 | default int[] aryEq(int[] value) {
263 | return AdditionalMatchers.aryEq(value);
264 | }
265 |
266 | /**
267 | * Delegates call to {@link AdditionalMatchers#aryEq(float[])}.
268 | */
269 | default float[] aryEq(float[] value) {
270 | return AdditionalMatchers.aryEq(value);
271 | }
272 |
273 | /**
274 | * Delegates call to {@link AdditionalMatchers#aryEq(double[])}.
275 | */
276 | default double[] aryEq(double[] value) {
277 | return AdditionalMatchers.aryEq(value);
278 | }
279 |
280 | /**
281 | * Delegates call to {@link AdditionalMatchers#aryEq(char[])}.
282 | */
283 | default char[] aryEq(char[] value) {
284 | return AdditionalMatchers.aryEq(value);
285 | }
286 |
287 | /**
288 | * Delegates call to {@link AdditionalMatchers#aryEq(byte[])}.
289 | */
290 | default byte[] aryEq(byte[] value) {
291 | return AdditionalMatchers.aryEq(value);
292 | }
293 |
294 | /**
295 | * Delegates call to {@link AdditionalMatchers#aryEq(boolean[])}.
296 | */
297 | default boolean[] aryEq(boolean[] value) {
298 | return AdditionalMatchers.aryEq(value);
299 | }
300 |
301 | /**
302 | * Delegates call to {@link AdditionalMatchers#and(boolean, boolean)}.
303 | */
304 | default boolean and(boolean first, boolean second) {
305 | return AdditionalMatchers.and(first, second);
306 | }
307 |
308 | /**
309 | * Delegates call to {@link AdditionalMatchers#and(byte, byte)}.
310 | */
311 | default byte and(byte first, byte second) {
312 | return AdditionalMatchers.and(first, second);
313 | }
314 |
315 | /**
316 | * Delegates call to {@link AdditionalMatchers#and(char, char)}.
317 | */
318 | default char and(char first, char second) {
319 | return AdditionalMatchers.and(first, second);
320 | }
321 |
322 | /**
323 | * Delegates call to {@link AdditionalMatchers#and(double, double)}.
324 | */
325 | default double and(double first, double second) {
326 | return AdditionalMatchers.and(first, second);
327 | }
328 |
329 | /**
330 | * Delegates call to {@link AdditionalMatchers#and(float, float)}.
331 | */
332 | default float and(float first, float second) {
333 | return AdditionalMatchers.and(first, second);
334 | }
335 |
336 | /**
337 | * Delegates call to {@link AdditionalMatchers#and(int, int)}.
338 | */
339 | default int and(int first, int second) {
340 | return AdditionalMatchers.and(first, second);
341 | }
342 |
343 | /**
344 | * Delegates call to {@link AdditionalMatchers#and(long, long)}.
345 | */
346 | default long and(long first, long second) {
347 | return AdditionalMatchers.and(first, second);
348 | }
349 |
350 | /**
351 | * Delegates call to {@link AdditionalMatchers#and(short, short)}.
352 | */
353 | default short and(short first, short second) {
354 | return AdditionalMatchers.and(first, second);
355 | }
356 |
357 | /**
358 | * Delegates call to {@link AdditionalMatchers#and(T, T)}.
359 | */
360 | default T and(T first, T second) {
361 | return AdditionalMatchers.and(first, second);
362 | }
363 |
364 | /**
365 | * Delegates call to {@link AdditionalMatchers#or(boolean, boolean)}.
366 | */
367 | default boolean or(boolean first, boolean second) {
368 | return AdditionalMatchers.or(first, second);
369 | }
370 |
371 | /**
372 | * Delegates call to {@link AdditionalMatchers#or(T, T)}.
373 | */
374 | default T or(T first, T second) {
375 | return AdditionalMatchers.or(first, second);
376 | }
377 |
378 | /**
379 | * Delegates call to {@link AdditionalMatchers#or(short, short)}.
380 | */
381 | default short or(short first, short second) {
382 | return AdditionalMatchers.or(first, second);
383 | }
384 |
385 | /**
386 | * Delegates call to {@link AdditionalMatchers#or(long, long)}.
387 | */
388 | default long or(long first, long second) {
389 | return AdditionalMatchers.or(first, second);
390 | }
391 |
392 | /**
393 | * Delegates call to {@link AdditionalMatchers#or(int, int)}.
394 | */
395 | default int or(int first, int second) {
396 | return AdditionalMatchers.or(first, second);
397 | }
398 |
399 | /**
400 | * Delegates call to {@link AdditionalMatchers#or(float, float)}.
401 | */
402 | default float or(float first, float second) {
403 | return AdditionalMatchers.or(first, second);
404 | }
405 |
406 | /**
407 | * Delegates call to {@link AdditionalMatchers#or(double, double)}.
408 | */
409 | default double or(double first, double second) {
410 | return AdditionalMatchers.or(first, second);
411 | }
412 |
413 | /**
414 | * Delegates call to {@link AdditionalMatchers#or(char, char)}.
415 | */
416 | default char or(char first, char second) {
417 | return AdditionalMatchers.or(first, second);
418 | }
419 |
420 | /**
421 | * Delegates call to {@link AdditionalMatchers#or(byte, byte)}.
422 | */
423 | default byte or(byte first, byte second) {
424 | return AdditionalMatchers.or(first, second);
425 | }
426 |
427 | /**
428 | * Delegates call to {@link AdditionalMatchers#not(T)}.
429 | */
430 | default T not(T first) {
431 | return AdditionalMatchers.not(first);
432 | }
433 |
434 | /**
435 | * Delegates call to {@link AdditionalMatchers#not(short)}.
436 | */
437 | default short not(short first) {
438 | return AdditionalMatchers.not(first);
439 | }
440 |
441 | /**
442 | * Delegates call to {@link AdditionalMatchers#not(int)}.
443 | */
444 | default int not(int first) {
445 | return AdditionalMatchers.not(first);
446 | }
447 |
448 | /**
449 | * Delegates call to {@link AdditionalMatchers#not(long)}.
450 | */
451 | default long not(long first) {
452 | return AdditionalMatchers.not(first);
453 | }
454 |
455 | /**
456 | * Delegates call to {@link AdditionalMatchers#not(float)}.
457 | */
458 | default float not(float first) {
459 | return AdditionalMatchers.not(first);
460 | }
461 |
462 | /**
463 | * Delegates call to {@link AdditionalMatchers#not(double)}.
464 | */
465 | default double not(double first) {
466 | return AdditionalMatchers.not(first);
467 | }
468 |
469 | /**
470 | * Delegates call to {@link AdditionalMatchers#not(char)}.
471 | */
472 | default char not(char first) {
473 | return AdditionalMatchers.not(first);
474 | }
475 |
476 | /**
477 | * Delegates call to {@link AdditionalMatchers#not(boolean)}.
478 | */
479 | default boolean not(boolean first) {
480 | return AdditionalMatchers.not(first);
481 | }
482 |
483 | /**
484 | * Delegates call to {@link AdditionalMatchers#not(byte)}.
485 | */
486 | default byte not(byte first) {
487 | return AdditionalMatchers.not(first);
488 | }
489 |
490 | /**
491 | * Delegates call to {@link AdditionalMatchers#eq(double, double)}.
492 | */
493 | default double eq(double value, double delta) {
494 | return AdditionalMatchers.eq(value, delta);
495 | }
496 |
497 | /**
498 | * Delegates call to {@link AdditionalMatchers#eq(float, float)}.
499 | */
500 | default float eq(float value, float delta) {
501 | return AdditionalMatchers.eq(value, delta);
502 | }
503 | }
504 |
--------------------------------------------------------------------------------
/src/main/java/info/solidsoft/mockito/java8/api/WithBDDMockito.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Mockito contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8.api;
7 |
8 | import org.mockito.BDDMockito;
9 | import org.mockito.Incubating;
10 | import org.mockito.stubbing.Answer;
11 |
12 | /**
13 | * An entry point to Mockito stubbing/mocking API in BDD style with basic matchers.
14 | *
15 | * Created as an alternative approach to static imports. A test class can implement that interface to make all
16 | * the methods from {@link BDDMockito} class directly available.
17 | *
18 | * Sample test in Behavior-driven development style:
19 | *
20 | *
21 | * //no static Mockito imports needed!
22 | *
23 | * class ShopTest implements WithMockito {
24 | *
25 | * private Seller seller = mock(Seller.class);
26 | * private Shop shop = new Shop(seller);
27 | *
28 | * public void shouldBuyBread() {
29 | * //given
30 | * given(seller.askForBread()).willReturn(new Bread());
31 | * //when
32 | * Goods goods = shop.buyBread();
33 | * //then
34 | * assertThat(goods.containBread()).isTrue();
35 | * }
36 | * }
37 | *
38 | *
39 | *
40 | * For BDD style mock verification {@link BDDMockito.Then} can be used:
41 | *
42 | * person.ride(bike);
43 | * person.ride(bike);
44 | *
45 | * then(person).should(times(2)).ride(bike);
46 | * then(police).shouldHaveZeroInteractions();
47 | *
48 | *
49 | * See {@link WithMockito} if Arrange-Act-Assert approach is preferred over BDD.
50 | *
51 | * If more sophisticated matchers are needed see {@link WithAdditionalMatchers} interface.
52 | *
53 | * Based on an idea proposed by David Gageot:
54 | * http://blog.javabien.net/2014/04/23/what-if-assertj-used-java-8/
55 | *
56 | * @see WithMockito
57 | * @see WithAdditionalMatchers
58 | *
59 | * @author Marcin Zajączkowski
60 | * @since 1.0.0
61 | */
62 | @Incubating
63 | public interface WithBDDMockito extends WithMockito {
64 |
65 | /**
66 | * Delegates call to {@link BDDMockito#given(Object)}
67 | */
68 | default BDDMockito.BDDMyOngoingStubbing given(T methodCall) {
69 | return BDDMockito.given(methodCall);
70 | }
71 |
72 | /**
73 | * Delegates call to {@link BDDMockito#then(Object)}
74 | */
75 | default BDDMockito.Then then(T mock) {
76 | return BDDMockito.then(mock);
77 | }
78 |
79 | /**
80 | * Delegates call to {@link BDDMockito#willThrow(Throwable...)}
81 | */
82 | default BDDMockito.BDDStubber willThrow(Throwable... toBeThrown) {
83 | return BDDMockito.willThrow(toBeThrown);
84 | }
85 |
86 | /**
87 | * Delegates call to {@link BDDMockito#willThrow(Class)}
88 | */
89 | default BDDMockito.BDDStubber willThrow(Class extends Throwable> toBeThrown) {
90 | return BDDMockito.willThrow(toBeThrown);
91 | }
92 |
93 | /**
94 | * Delegates call to {@link BDDMockito#doAnswer(Answer)}
95 | */
96 | default BDDMockito.BDDStubber willAnswer(Answer answer) {
97 | return BDDMockito.willAnswer(answer);
98 | }
99 |
100 | /**
101 | * Delegates call to {@link BDDMockito#doNothing()}
102 | */
103 | default BDDMockito.BDDStubber willDoNothing() {
104 | return BDDMockito.willDoNothing();
105 | }
106 |
107 | /**
108 | * Delegates call to {@link BDDMockito#doReturn(Object)}
109 | */
110 | default BDDMockito.BDDStubber willReturn(Object toBeReturned) {
111 | return BDDMockito.willReturn(toBeReturned);
112 | }
113 |
114 | /**
115 | * Delegates call to {@link BDDMockito#doReturn(Object, Object...)}
116 | */
117 | default BDDMockito.BDDStubber willReturn(Object toBeReturned, Object... toBeReturnedNext) {
118 | return BDDMockito.willReturn(toBeReturned, toBeReturnedNext);
119 | }
120 |
121 | /**
122 | * Delegates call to {@link BDDMockito#doCallRealMethod()}
123 | */
124 | default BDDMockito.BDDStubber willCallRealMethod() {
125 | return BDDMockito.willCallRealMethod();
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/main/java/info/solidsoft/mockito/java8/api/WithMatchers.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Mockito contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8.api;
7 |
8 | import org.mockito.ArgumentMatcher;
9 | import org.mockito.ArgumentMatchers;
10 |
11 | import java.util.Collection;
12 | import java.util.List;
13 | import java.util.Map;
14 | import java.util.Set;
15 |
16 | /**
17 | * An internal interface being an entry point to Mockito basic matchers.
18 | *
19 | * Created only to organize internal entry points structure. Basic matchers are transitively available via
20 | * {@link WithBDDMockito} and {@link WithMockito} interfaces. Additional matcher are available via
21 | * {@link WithAdditionalMatchers} interface.
22 | *
23 | * @see WithAdditionalMatchers
24 | * @see WithBDDMockito
25 | * @see WithMockito
26 | *
27 | * @author Marcin Zajączkowski
28 | * @since 1.0.0
29 | */
30 | interface WithMatchers {
31 |
32 | /**
33 | * Delegates call to {@link ArgumentMatchers#anyBoolean()}.
34 | */
35 | default boolean anyBoolean() {
36 | return ArgumentMatchers.anyBoolean();
37 | }
38 |
39 | /**
40 | * Delegates call to {@link ArgumentMatchers#anyByte()}.
41 | */
42 | default byte anyByte() {
43 | return ArgumentMatchers.anyByte();
44 | }
45 |
46 | /**
47 | * Delegates call to {@link ArgumentMatchers#anyChar()}.
48 | */
49 | default char anyChar() {
50 | return ArgumentMatchers.anyChar();
51 | }
52 |
53 | /**
54 | * Delegates call to {@link ArgumentMatchers#anyInt()}.
55 | */
56 | default int anyInt() {
57 | return ArgumentMatchers.anyInt();
58 | }
59 |
60 | /**
61 | * Delegates call to {@link ArgumentMatchers#anyLong()}.
62 | */
63 | default long anyLong() {
64 | return ArgumentMatchers.anyLong();
65 | }
66 |
67 | /**
68 | * Delegates call to {@link ArgumentMatchers#anyFloat()}.
69 | */
70 | default float anyFloat() {
71 | return ArgumentMatchers.anyFloat();
72 | }
73 |
74 | /**
75 | * Delegates call to {@link ArgumentMatchers#anyDouble()}.
76 | */
77 | default double anyDouble() {
78 | return ArgumentMatchers.anyDouble();
79 | }
80 |
81 | /**
82 | * Delegates call to {@link ArgumentMatchers#anyShort()}.
83 | */
84 | default short anyShort() {
85 | return ArgumentMatchers.anyShort();
86 | }
87 |
88 | /**
89 | * Delegates call to {@link ArgumentMatchers#anyObject()}.
90 | *
91 | * @deprecated This will be removed in Mockito 3.0.
92 | */
93 | @Deprecated
94 | default T anyObject() {
95 | return ArgumentMatchers.anyObject();
96 | }
97 |
98 | /**
99 | * Delegates call to {@link ArgumentMatchers#anyVararg()}.
100 | *
101 | * @deprecated This will be removed in Mockito 3.0.
102 | */
103 | @Deprecated
104 | default T anyVararg() {
105 | return ArgumentMatchers.anyVararg();
106 | }
107 |
108 | /**
109 | * Delegates call to {@link ArgumentMatchers#any(Class)}.
110 | */
111 | default T any(Class clazz) {
112 | return ArgumentMatchers.any(clazz);
113 | }
114 |
115 | /**
116 | * Delegates call to {@link ArgumentMatchers#any()}.
117 | */
118 | default T any() {
119 | return ArgumentMatchers.any();
120 | }
121 |
122 | /**
123 | * Delegates call to {@link ArgumentMatchers#anyString()}.
124 | */
125 | default String anyString() {
126 | return ArgumentMatchers.anyString();
127 | }
128 |
129 | /**
130 | * Delegates call to {@link ArgumentMatchers#anyList()}.
131 | */
132 | default List anyList() {
133 | return ArgumentMatchers.anyList();
134 | }
135 |
136 | /**
137 | * Delegates call to {@link ArgumentMatchers#anyListOf(Class)}.
138 | *
139 | * @deprecated This will be removed in Mockito 3.0.
140 | */
141 | @Deprecated
142 | default List anyListOf(Class clazz) {
143 | return ArgumentMatchers.anyListOf(clazz);
144 | }
145 |
146 | /**
147 | * Delegates call to {@link ArgumentMatchers#anySet()}.
148 | */
149 | default Set anySet() {
150 | return ArgumentMatchers.anySet();
151 | }
152 |
153 | /**
154 | * Delegates call to {@link ArgumentMatchers#anySetOf(Class)}.
155 | *
156 | * @deprecated This will be removed in Mockito 3.0.
157 | */
158 | @Deprecated
159 | default Set anySetOf(Class clazz) {
160 | return ArgumentMatchers.anySetOf(clazz);
161 | }
162 |
163 | /**
164 | * Delegates call to {@link ArgumentMatchers#anyMap()}.
165 | */
166 | default Map anyMap() {
167 | return ArgumentMatchers.anyMap();
168 | }
169 |
170 | /**
171 | * Delegates call to {@link ArgumentMatchers#anyMapOf(Class, Class)}.
172 | *
173 | * @deprecated This will be removed in Mockito 3.0.
174 | */
175 | @Deprecated
176 | default Map anyMapOf(Class keyClazz, Class valueClazz) {
177 | return ArgumentMatchers.anyMapOf(keyClazz, valueClazz);
178 | }
179 |
180 | /**
181 | * Delegates call to {@link ArgumentMatchers#anyCollection()}.
182 | */
183 | default Collection anyCollection() {
184 | return ArgumentMatchers.anyCollection();
185 | }
186 |
187 | /**
188 | * Delegates call to {@link ArgumentMatchers#anyCollectionOf(Class)}.
189 | *
190 | * @deprecated This will be removed in Mockito 3.0.
191 | */
192 | @Deprecated
193 | default Collection anyCollectionOf(Class clazz) {
194 | return ArgumentMatchers.anyCollectionOf(clazz);
195 | }
196 |
197 | /**
198 | * Delegates call to {@link ArgumentMatchers#anyIterable()}.
199 | *
200 | * @since 2.0.0
201 | */
202 | default Iterable anyIterable() {
203 | return ArgumentMatchers.anyIterable();
204 | }
205 |
206 | /**
207 | * Delegates call to {@link ArgumentMatchers#anyIterableOf(Class)}.
208 | *
209 | * @since 2.0.0
210 | * @deprecated This will be removed in Mockito 3.0.
211 | */
212 | @Deprecated
213 | default Iterable anyIterableOf(Class clazz) {
214 | return ArgumentMatchers.anyIterableOf(clazz);
215 | }
216 |
217 | /**
218 | * Delegates call to {@link ArgumentMatchers#isA(Class)}.
219 | */
220 | default T isA(Class clazz) {
221 | return ArgumentMatchers.isA(clazz);
222 | }
223 |
224 | /**
225 | * Delegates call to {@link ArgumentMatchers#eq(boolean)}.
226 | */
227 | default boolean eq(boolean value) {
228 | return ArgumentMatchers.eq(value);
229 | }
230 |
231 | /**
232 | * Delegates call to {@link ArgumentMatchers#eq(byte)}.
233 | */
234 | default byte eq(byte value) {
235 | return ArgumentMatchers.eq(value);
236 | }
237 |
238 | /**
239 | * Delegates call to {@link ArgumentMatchers#eq(char)}.
240 | */
241 | default char eq(char value) {
242 | return ArgumentMatchers.eq(value);
243 | }
244 |
245 | /**
246 | * Delegates call to {@link ArgumentMatchers#eq(double)}.
247 | */
248 | default double eq(double value) {
249 | return ArgumentMatchers.eq(value);
250 | }
251 |
252 | /**
253 | * Delegates call to {@link ArgumentMatchers#eq(float)}.
254 | */
255 | default float eq(float value) {
256 | return ArgumentMatchers.eq(value);
257 | }
258 |
259 | /**
260 | * Delegates call to {@link ArgumentMatchers#eq(int)}.
261 | */
262 | default int eq(int value) {
263 | return ArgumentMatchers.eq(value);
264 | }
265 |
266 | /**
267 | * Delegates call to {@link ArgumentMatchers#eq(long)}.
268 | */
269 | default long eq(long value) {
270 | return ArgumentMatchers.eq(value);
271 | }
272 |
273 | /**
274 | * Delegates call to {@link ArgumentMatchers#eq(short)}.
275 | */
276 | default short eq(short value) {
277 | return ArgumentMatchers.eq(value);
278 | }
279 |
280 | /**
281 | * Delegates call to {@link ArgumentMatchers#eq(T)}.
282 | */
283 | default T eq(T value) {
284 | return ArgumentMatchers.eq(value);
285 | }
286 |
287 | /**
288 | * Delegates call to {@link ArgumentMatchers#refEq(T, String...)}.
289 | */
290 | default T refEq(T value, String... excludeFields) {
291 | return ArgumentMatchers.refEq(value, excludeFields);
292 | }
293 |
294 | /**
295 | * Delegates call to {@link ArgumentMatchers#same(T)}.
296 | */
297 | default T same(T value) {
298 | return ArgumentMatchers.same(value);
299 | }
300 |
301 | /**
302 | * Delegates call to {@link ArgumentMatchers#isNull()}.
303 | */
304 | default T isNull() {
305 | return ArgumentMatchers.isNull();
306 | }
307 |
308 | /**
309 | * Delegates call to {@link ArgumentMatchers#isNull(Class)}.
310 | *
311 | * @deprecated This will be removed in Mockito 3.0.
312 | */
313 | @Deprecated
314 | default T isNull(Class clazz) {
315 | return ArgumentMatchers.isNull(clazz);
316 | }
317 |
318 | /**
319 | * Delegates call to {@link ArgumentMatchers#notNull()}.
320 | */
321 | default T notNull() {
322 | return ArgumentMatchers.notNull();
323 | }
324 |
325 | /**
326 | * Delegates call to {@link ArgumentMatchers#notNull(Class)}.
327 | *
328 | * @deprecated This will be removed in Mockito 3.0.
329 | */
330 | @Deprecated
331 | default T notNull(Class clazz) {
332 | return ArgumentMatchers.notNull(clazz);
333 | }
334 |
335 | /**
336 | * Delegates call to {@link ArgumentMatchers#isNotNull()}.
337 | */
338 | default T isNotNull() {
339 | return ArgumentMatchers.isNotNull();
340 | }
341 |
342 | /**
343 | * Delegates call to {@link ArgumentMatchers#isNotNull(Class)}.
344 | *
345 | * @deprecated This will be removed in Mockito 3.0.
346 | */
347 | @Deprecated
348 | default T isNotNull(Class clazz) {
349 | return ArgumentMatchers.isNotNull(clazz);
350 | }
351 |
352 | /**
353 | * Delegates call to {@link ArgumentMatchers#contains(String)}.
354 | */
355 | default String contains(String substring) {
356 | return ArgumentMatchers.contains(substring);
357 | }
358 |
359 | /**
360 | * Delegates call to {@link ArgumentMatchers#matches(String)}.
361 | */
362 | default String matches(String regex) {
363 | return ArgumentMatchers.matches(regex);
364 | }
365 |
366 | /**
367 | * Delegates call to {@link ArgumentMatchers#endsWith(String)}.
368 | */
369 | default String endsWith(String suffix) {
370 | return ArgumentMatchers.endsWith(suffix);
371 | }
372 |
373 | /**
374 | * Delegates call to {@link ArgumentMatchers#startsWith(String)}.
375 | */
376 | default String startsWith(String prefix) {
377 | return ArgumentMatchers.startsWith(prefix);
378 | }
379 |
380 | /**
381 | * Delegates call to {@link ArgumentMatchers#argThat(ArgumentMatcher)}.
382 | */
383 | default T argThat(ArgumentMatcher matcher) {
384 | return ArgumentMatchers.argThat(matcher);
385 | }
386 |
387 | /**
388 | * Delegates call to {@link ArgumentMatchers#charThat(ArgumentMatcher)}.
389 | */
390 | default char charThat(ArgumentMatcher matcher) {
391 | return ArgumentMatchers.charThat(matcher);
392 | }
393 |
394 | /**
395 | * Delegates call to {@link ArgumentMatchers#booleanThat(ArgumentMatcher)}.
396 | */
397 | default boolean booleanThat(ArgumentMatcher matcher) {
398 | return ArgumentMatchers.booleanThat(matcher);
399 | }
400 |
401 | /**
402 | * Delegates call to {@link ArgumentMatchers#byteThat(ArgumentMatcher)}.
403 | */
404 | default byte byteThat(ArgumentMatcher matcher) {
405 | return ArgumentMatchers.byteThat(matcher);
406 | }
407 |
408 | /**
409 | * Delegates call to {@link ArgumentMatchers#shortThat(ArgumentMatcher)}.
410 | */
411 | default short shortThat(ArgumentMatcher matcher) {
412 | return ArgumentMatchers.shortThat(matcher);
413 | }
414 |
415 | /**
416 | * Delegates call to {@link ArgumentMatchers#intThat(ArgumentMatcher)}.
417 | */
418 | default int intThat(ArgumentMatcher matcher) {
419 | return ArgumentMatchers.intThat(matcher);
420 | }
421 |
422 | /**
423 | * Delegates call to {@link ArgumentMatchers#longThat(ArgumentMatcher)}.
424 | */
425 | default long longThat(ArgumentMatcher matcher) {
426 | return ArgumentMatchers.longThat(matcher);
427 | }
428 |
429 | /**
430 | * Delegates call to {@link ArgumentMatchers#floatThat(ArgumentMatcher)}.
431 | */
432 | default float floatThat(ArgumentMatcher matcher) {
433 | return ArgumentMatchers.floatThat(matcher);
434 | }
435 |
436 | /**
437 | * Delegates call to {@link ArgumentMatchers#doubleThat(ArgumentMatcher)}.
438 | */
439 | default double doubleThat(ArgumentMatcher matcher) {
440 | return ArgumentMatchers.doubleThat(matcher);
441 | }
442 | }
443 |
--------------------------------------------------------------------------------
/src/main/java/info/solidsoft/mockito/java8/api/WithMockito.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Mockito contributors.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8.api;
7 |
8 | import org.mockito.InOrder;
9 | import org.mockito.Incubating;
10 | import org.mockito.MockSettings;
11 | import org.mockito.MockingDetails;
12 | import org.mockito.Mockito;
13 | import org.mockito.stubbing.Answer;
14 | import org.mockito.stubbing.OngoingStubbing;
15 | import org.mockito.stubbing.Stubber;
16 | import org.mockito.verification.VerificationAfterDelay;
17 | import org.mockito.verification.VerificationMode;
18 | import org.mockito.verification.VerificationWithTimeout;
19 |
20 | /**
21 | * An entry point to classic Mockito stubbing/mocking API with basic matchers.
22 | *
23 | * Created as an alternative approach to static imports. A test class can implement that interface to make all
24 | * the methods from {@link Mockito} class directly available.
25 | *
26 | *
27 | * Sample test in Arrange-Act-Assert style:
28 | *
29 | *
30 | * //no static Mockito imports needed!
31 | *
32 | * class ShopTest implements WithMockito {
33 | *
34 | * private Seller seller = mock(Seller.class);
35 | * private Shop shop = new Shop(seller);
36 | *
37 | * public void shouldBuyBread() {
38 | * //arrange
39 | * when(seller.askForBread()).thenReturn(new Bread());
40 | * //act
41 | * Goods goods = shop.buyBread();
42 | * //assert
43 | * assertThat(goods.containBread()).isTrue();
44 | * }
45 | * }
46 | *
47 | *
48 | * Mock verification can be then performed with {@link Mockito#verify(Object)} method:
49 | *
50 | *
51 | * person.ride(bike);
52 | * person.ride(bike);
53 | *
54 | * verify(person, times(2)).ride(bike);
55 | * verifyNoMoreInteractions(police);
56 | *
57 | *
58 | * In many cases Behavior-driven development style may be preferred. See {@link WithBDDMockito} how it can be used
59 | * with Mockito.
60 | *
61 | * If more sophisticated matchers are needed see {@link WithAdditionalMatchers} interface.
62 | *
63 | * Based on an idea proposed by David Gageot:
64 | * http://blog.javabien.net/2014/04/23/what-if-assertj-used-java-8/
65 | *
66 | * @see WithBDDMockito
67 | * @see WithAdditionalMatchers
68 | *
69 | * @author Marcin Zajączkowski
70 | * @since 1.0.0
71 | */
72 | @Incubating
73 | public interface WithMockito extends WithMatchers {
74 |
75 | /**
76 | * Delegates call to {@link Mockito#mock(Class)}.
77 | */
78 | default T mock(Class classToMock) {
79 | return Mockito.mock(classToMock);
80 | }
81 |
82 | /**
83 | * Delegates call to {@link Mockito#mock(Class, String)}.
84 | */
85 | default T mock(Class classToMock, String name) {
86 | return Mockito.mock(classToMock, name);
87 | }
88 |
89 | /**
90 | * Delegates call to {@link Mockito#mockingDetails(Object)}.
91 | */
92 | default MockingDetails mockingDetails(Object toInspect) {
93 | return Mockito.mockingDetails(toInspect);
94 | }
95 |
96 | /**
97 | * Delegates call to {@link Mockito#mock(Class, Answer)}.
98 | */
99 | default T mock(Class classToMock, Answer defaultAnswer) {
100 | return Mockito.mock(classToMock, defaultAnswer);
101 | }
102 |
103 | /**
104 | * Delegates call to {@link Mockito#mock(Class, MockSettings)}.
105 | */
106 | default T mock(Class classToMock, MockSettings mockSettings) {
107 | return Mockito.mock(classToMock, mockSettings);
108 | }
109 |
110 | /**
111 | * Delegates call to {@link Mockito#spy(Object)}.
112 | */
113 | default T spy(T object) {
114 | return Mockito.spy(object);
115 | }
116 |
117 | /**
118 | * Delegates call to {@link Mockito#spy(Class)}.
119 | */
120 | @Incubating
121 | default T spy(Class classToSpy) {
122 | return Mockito.spy(classToSpy);
123 | }
124 |
125 | /**
126 | * Delegates call to {@link Mockito#when(Object)}.
127 | */
128 | default OngoingStubbing when(T methodCall) {
129 | return Mockito.when(methodCall);
130 | }
131 |
132 | /**
133 | * Delegates call to {@link Mockito#verify(Object)}.
134 | */
135 | default T verify(T mock) {
136 | return Mockito.verify(mock, times(1));
137 | }
138 |
139 | /**
140 | * Delegates call to {@link Mockito#verify(Object, VerificationMode)}.
141 | */
142 | default T verify(T mock, VerificationMode mode) {
143 | return Mockito.verify(mock, mode);
144 | }
145 |
146 | /**
147 | * Delegates call to {@link Mockito#reset(Object[])}.
148 | */
149 | default void reset(T ... mocks) {
150 | Mockito.reset(mocks);
151 | }
152 |
153 | /**
154 | * Delegates call to {@link Mockito#verifyNoMoreInteractions(Object...)}.
155 | */
156 | default void verifyNoMoreInteractions(Object... mocks) {
157 | Mockito.verifyNoMoreInteractions(mocks);
158 | }
159 |
160 | /**
161 | * Delegates call to {@link Mockito#verifyZeroInteractions(Object...)}.
162 | */
163 | default void verifyZeroInteractions(Object... mocks) {
164 | Mockito.verifyNoMoreInteractions(mocks);
165 | }
166 |
167 | /**
168 | * Delegates call to {@link Mockito#doThrow(Throwable...)}.
169 | */
170 | default Stubber doThrow(Throwable... toBeThrown) {
171 | return Mockito.doThrow(toBeThrown);
172 | }
173 |
174 | /**
175 | * Delegates call to {@link Mockito#doThrow(Class)}.
176 | */
177 | default Stubber doThrow(Class extends Throwable> toBeThrown) {
178 | return Mockito.doThrow(toBeThrown);
179 | }
180 |
181 | /**
182 | * Delegates call to {@link Mockito#doCallRealMethod()}.
183 | */
184 | default Stubber doCallRealMethod() {
185 | return Mockito.doCallRealMethod();
186 | }
187 |
188 | /**
189 | * Delegates call to {@link Mockito#doAnswer(Answer)}.
190 | */
191 | default Stubber doAnswer(Answer answer) {
192 | return Mockito.doAnswer(answer);
193 | }
194 |
195 | /**
196 | * Delegates call to {@link Mockito#doNothing()}.
197 | */
198 | default Stubber doNothing() {
199 | return Mockito.doNothing();
200 | }
201 |
202 | /**
203 | * Delegates call to {@link Mockito#doReturn(Object)}.
204 | */
205 | default Stubber doReturn(Object toBeReturned) {
206 | return Mockito.doReturn(toBeReturned);
207 | }
208 |
209 | /**
210 | * Delegates call to {@link Mockito#doReturn(Object, Object...)}.
211 | */
212 | default Stubber doReturn(Object toBeReturned, Object... toBeReturnedNext) {
213 | return Mockito.doReturn(toBeReturned, toBeReturnedNext);
214 | }
215 |
216 | /**
217 | * Delegates call to {@link Mockito#inOrder(Object...)}.
218 | */
219 | default InOrder inOrder(Object... mocks) {
220 | return Mockito.inOrder(mocks);
221 | }
222 |
223 | /**
224 | * Delegates call to {@link Mockito#ignoreStubs(Object...)}.
225 | */
226 | default Object[] ignoreStubs(Object... mocks) {
227 | return Mockito.ignoreStubs(mocks);
228 | }
229 |
230 | /**
231 | * Delegates call to {@link Mockito#times(int)}.
232 | */
233 | default VerificationMode times(int wantedNumberOfInvocations) {
234 | return Mockito.times(wantedNumberOfInvocations);
235 | }
236 |
237 | /**
238 | * Delegates call to {@link Mockito#never()}.
239 | */
240 | default VerificationMode never() {
241 | return Mockito.never();
242 | }
243 |
244 | /**
245 | * Delegates call to {@link Mockito#atLeastOnce()}.
246 | */
247 | default VerificationMode atLeastOnce() {
248 | return Mockito.atLeastOnce();
249 | }
250 |
251 | /**
252 | * Delegates call to {@link Mockito#atLeast(int)}.
253 | */
254 | default VerificationMode atLeast(int minNumberOfInvocations) {
255 | return Mockito.atLeast(minNumberOfInvocations);
256 | }
257 |
258 | /**
259 | * Delegates call to {@link Mockito#atMost(int)}.
260 | */
261 | default VerificationMode atMost(int maxNumberOfInvocations) {
262 | return Mockito.atMost(maxNumberOfInvocations);
263 | }
264 |
265 | /**
266 | * Delegates call to {@link Mockito#calls(int)}.
267 | */
268 | default VerificationMode calls(int wantedNumberOfInvocations){
269 | return Mockito.calls(wantedNumberOfInvocations);
270 | }
271 |
272 | /**
273 | * Delegates call to {@link Mockito#only()}.
274 | */
275 | default VerificationMode only() {
276 | return Mockito.only();
277 | }
278 |
279 | /**
280 | * Delegates call to {@link Mockito#timeout(long)}.
281 | */
282 | default VerificationWithTimeout timeout(long millis) {
283 | return Mockito.timeout(millis);
284 | }
285 |
286 | /**
287 | * Delegates call to {@link Mockito#after(long)}.
288 | */
289 | default VerificationAfterDelay after(long millis) {
290 | return Mockito.after(millis);
291 | }
292 |
293 | /**
294 | * Delegates call to {@link Mockito#validateMockitoUsage()}.
295 | */
296 | default void validateMockitoUsage() {
297 | Mockito.validateMockitoUsage();
298 | }
299 |
300 | /**
301 | * Delegates call to {@link Mockito#withSettings()}.
302 | */
303 | default MockSettings withSettings() {
304 | return Mockito.withSettings();
305 | }
306 |
307 | /**
308 | * Delegates call to {@link Mockito#description(String)}.
309 | *
310 | * @since 2.0.0
311 | */
312 | default VerificationMode description(String description) {
313 | return Mockito.description(description);
314 | }
315 | }
316 |
--------------------------------------------------------------------------------
/src/test/java/info/solidsoft/mockito/java8/AssertionMatcherTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Marcin Zajączkowski.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8;
7 |
8 | import info.solidsoft.mockito.java8.domain.ShipSearchCriteria;
9 | import info.solidsoft.mockito.java8.domain.TacticalStation;
10 | import org.assertj.core.api.ThrowableAssert;
11 | import org.junit.jupiter.api.Test;
12 | import org.junit.jupiter.api.extension.ExtendWith;
13 | import org.mockito.ArgumentCaptor;
14 | import org.mockito.Mock;
15 | import org.mockito.junit.jupiter.MockitoExtension;
16 |
17 | import java.io.IOException;
18 |
19 | import static info.solidsoft.mockito.java8.AssertionMatcher.assertArg;
20 | import static info.solidsoft.mockito.java8.AssertionMatcher.assertArgThrowing;
21 | import static org.assertj.core.api.Assertions.assertThat;
22 | import static org.assertj.core.api.Assertions.assertThatThrownBy;
23 | import static org.mockito.Mockito.verify;
24 |
25 | @ExtendWith(MockitoExtension.class)
26 | class AssertionMatcherTest {
27 |
28 | @Mock
29 | private TacticalStation ts;
30 |
31 | private ShipSearchCriteria searchCriteria = new ShipSearchCriteria(1000, 4);
32 |
33 | @Test
34 | void shouldAllowToUseArgumentCaptorInClassicWay() {
35 | //when
36 | ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
37 | //then
38 | ArgumentCaptor captor = ArgumentCaptor.forClass(ShipSearchCriteria.class);
39 | verify(ts).findNumberOfShipsInRangeByCriteria(captor.capture());
40 | assertThat(captor.getValue().getMinimumRange()).isLessThan(2000);
41 | }
42 |
43 | @Test
44 | void shouldAllowToUseAssertionInLambda() {
45 | //when
46 | ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
47 | //then
48 | verify(ts).findNumberOfShipsInRangeByCriteria(assertArg(sc -> assertThat(sc.getMinimumRange()).isLessThan(2000)));
49 | }
50 |
51 | @Test
52 | void shouldAllowToUseAssertionInLambdaWithPrimitiveAsArgument() {
53 | //when
54 | ts.fireTorpedo(2);
55 | //then
56 | verify(ts).fireTorpedo(assertArg(i -> assertThat(i).isEqualTo(2)));
57 | }
58 |
59 | @Test
60 | void shouldHaveMeaningfulErrorMessage() {
61 | //when
62 | ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
63 | //then
64 | ThrowableAssert.ThrowingCallable verifyLambda = () -> {
65 | verify(ts).findNumberOfShipsInRangeByCriteria(assertArg(sc -> assertThat(sc.getMinimumRange()).isLessThan(50)));
66 | };
67 | assertThatThrownBy(verifyLambda)
68 | .isInstanceOf(AssertionError.class)
69 | .hasMessageContaining("Argument(s) are different! Wanted:\n" +
70 | "ts.findNumberOfShipsInRangeByCriteria(\n" +
71 | " AssertionMatcher reported: \n" +
72 | "Expecting:\n" +
73 | " <1000>\n" +
74 | "to be less than:\n" +
75 | " <50> ")
76 | .hasMessageContaining("Actual invocation has different arguments:\n" +
77 | "ts.findNumberOfShipsInRangeByCriteria(\n" +
78 | " ShipSearchCriteria{minimumRange=1000, numberOfPhasers=4}\n" +
79 | ");");
80 | }
81 |
82 | @SuppressWarnings("Convert2MethodRef")
83 | @Test
84 | void shouldAcceptLambdaWhichMayThrowCheckedException() {
85 | //when
86 | ts.fireTorpedo(2);
87 | //then
88 | verify(ts).fireTorpedo(assertArgThrowing(i -> methodDeclaringThrowingCheckedException(i)));
89 | }
90 |
91 | @Test
92 | void shouldAcceptMethodReferenceWhichMayThrowCheckedException() {
93 | //when
94 | ts.fireTorpedo(2);
95 | //then
96 | verify(ts).fireTorpedo(assertArgThrowing(this::methodDeclaringThrowingCheckedException));
97 | }
98 |
99 | @Test
100 | void shouldPropagateCheckedExceptionIfThrownInLambda() {
101 | //when
102 | ts.fireTorpedo(2);
103 | //then
104 | assertThatThrownBy(() -> verify(ts).fireTorpedo(assertArgThrowing(i -> {
105 | throw new IOException("Unexpected checked exception");
106 | })))
107 | .isInstanceOf(IOException.class);
108 | }
109 |
110 | private void methodDeclaringThrowingCheckedException(int i) throws Exception {
111 | assertThat(i).isEqualTo(2);
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/test/java/info/solidsoft/mockito/java8/LambdaMatcherStubbingTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Marcin Zajączkowski.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8;
7 |
8 | import info.solidsoft.mockito.java8.domain.ShipSearchCriteria;
9 | import info.solidsoft.mockito.java8.domain.TacticalStation;
10 | import org.junit.jupiter.api.Test;
11 | import org.junit.jupiter.api.extension.ExtendWith;
12 | import org.mockito.Mock;
13 | import org.mockito.invocation.InvocationOnMock;
14 | import org.mockito.junit.jupiter.MockitoExtension;
15 | import org.mockito.stubbing.Answer;
16 |
17 | import static info.solidsoft.mockito.java8.LambdaMatcher.argLambda;
18 | import static org.assertj.core.api.Assertions.assertThat;
19 | import static org.mockito.ArgumentMatchers.any;
20 | import static org.mockito.BDDMockito.given;
21 |
22 | @ExtendWith(MockitoExtension.class)
23 | class LambdaMatcherStubbingTest {
24 |
25 | @Mock
26 | private TacticalStation ts;
27 |
28 | @Test
29 | void shouldAllowToUseLambdaInStubbing() {
30 | //given
31 | given(ts.findNumberOfShipsInRangeByCriteria(argLambda(c -> c.getMinimumRange() > 1000))).willReturn(4);
32 | //expect
33 | assertThat(ts.findNumberOfShipsInRangeByCriteria(new ShipSearchCriteria(1500, 2))).isEqualTo(4);
34 | //expect
35 | assertThat(ts.findNumberOfShipsInRangeByCriteria(new ShipSearchCriteria(700, 2))).isEqualTo(0);
36 | }
37 |
38 | @SuppressWarnings("Convert2Lambda")
39 | @Test
40 | void stubbingWithCustomAnswerShouldBeLonger() {
41 | //given
42 | given(ts.findNumberOfShipsInRangeByCriteria(any())).willAnswer(new Answer() {
43 | @Override
44 | public Integer answer(InvocationOnMock invocation) throws Throwable {
45 | Object[] args = invocation.getArguments();
46 | ShipSearchCriteria criteria = (ShipSearchCriteria) args[0];
47 | if (criteria.getMinimumRange() > 1000) {
48 | return 4;
49 | } else {
50 | return 0;
51 | }
52 | }
53 | });
54 | //expect
55 | assertThat(ts.findNumberOfShipsInRangeByCriteria(new ShipSearchCriteria(1500, 2))).isEqualTo(4);
56 | //expect
57 | assertThat(ts.findNumberOfShipsInRangeByCriteria(new ShipSearchCriteria(700, 2))).isEqualTo(0);
58 | }
59 |
60 | @Test
61 | void stubbingWithCustomAnswerShouldBeLongerEvenAsLambda() {
62 | //given
63 | given(ts.findNumberOfShipsInRangeByCriteria(any())).willAnswer(invocation -> {
64 | ShipSearchCriteria criteria = (ShipSearchCriteria) invocation.getArguments()[0];
65 | return criteria.getMinimumRange() > 1000 ? 4 : 0;
66 | });
67 | //expect
68 | assertThat(ts.findNumberOfShipsInRangeByCriteria(new ShipSearchCriteria(1500, 2))).isEqualTo(4);
69 | //expect
70 | assertThat(ts.findNumberOfShipsInRangeByCriteria(new ShipSearchCriteria(700, 2))).isEqualTo(0);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/test/java/info/solidsoft/mockito/java8/LambdaMatcherTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Marcin Zajączkowski.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8;
7 |
8 | import info.solidsoft.mockito.java8.domain.ShipSearchCriteria;
9 | import info.solidsoft.mockito.java8.domain.TacticalStation;
10 | import org.assertj.core.api.ThrowableAssert;
11 | import org.junit.jupiter.api.Test;
12 | import org.junit.jupiter.api.extension.ExtendWith;
13 | import org.mockito.ArgumentMatcher;
14 | import org.mockito.Mock;
15 | import org.mockito.junit.jupiter.MockitoExtension;
16 |
17 | import java.io.IOException;
18 |
19 | import static info.solidsoft.mockito.java8.LambdaMatcher.argLambda;
20 | import static info.solidsoft.mockito.java8.LambdaMatcher.argLambdaThrowing;
21 | import static org.assertj.core.api.Assertions.assertThat;
22 | import static org.assertj.core.api.Assertions.assertThatThrownBy;
23 | import static org.mockito.ArgumentMatchers.argThat;
24 | import static org.mockito.Mockito.verify;
25 |
26 | @ExtendWith(MockitoExtension.class)
27 | class LambdaMatcherTest {
28 |
29 | private static final String UNEXPECTED_CHECKED_EXCEPTION_MESSAGE = "Unexpected checked exception";
30 |
31 | @Mock
32 | private TacticalStation ts;
33 |
34 | private ShipSearchCriteria searchCriteria = new ShipSearchCriteria(1000, 4);
35 |
36 | @Test
37 | void simpleBaseMatcherShouldWork() {
38 | //when
39 | int numberOfShips = ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
40 | //then
41 | assertThat(numberOfShips).isZero();
42 | //and
43 | verify(ts).findNumberOfShipsInRangeByCriteria(argThat(new ArgumentMatcher() {
44 | @Override
45 | public boolean matches(ShipSearchCriteria criteria) {
46 | return criteria.getMinimumRange() < 2000 && criteria.getNumberOfPhasers() > 2;
47 | }
48 |
49 | @Override
50 | public String toString() {
51 | return "ShipSearchCriteria minimumRange<2000 and numberOfPhasers>2";
52 | }
53 | }));
54 | }
55 |
56 | /*
57 | //Only as comparison - Hamcrest matchers are no longer on project classpath
58 | @Test
59 | void customMatcherShouldBeMoreCompact() {
60 | //when
61 | int numberOfShips = ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
62 | //then
63 | assertThat(numberOfShips).isZero();
64 | //and
65 | verify(ts).findNumberOfShipsInRangeByCriteria(argThat(new HamcrestArgumentMatcher<>(
66 | new CustomMatcher("ShipSearchCriteria minimumRange<2000 and numberOfPhasers>2") {
67 | @Override
68 | public boolean matches(Object item) {
69 | ShipSearchCriteria criteria = (ShipSearchCriteria) item;
70 | return criteria.getMinimumRange() < 2000 && criteria.getNumberOfPhasers() > 2;
71 | }
72 | })));
73 | }
74 | */
75 |
76 | @Test
77 | void argumentMatcherShouldBeEvenMoreCompact() {
78 | //when
79 | int numberOfShips = ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
80 | //then
81 | assertThat(numberOfShips).isZero();
82 | //and
83 | verify(ts).findNumberOfShipsInRangeByCriteria(argThat(new MoreThan2ShipsCloserThan2000()));
84 | }
85 |
86 | //TODO: 2000 -> 2 0 0 0 - useful anywhere? - worth to implement?
87 | private static class MoreThan2ShipsCloserThan2000 implements ArgumentMatcher {
88 | @Override
89 | public boolean matches(ShipSearchCriteria criteria) {
90 | return criteria.getMinimumRange() < 2000 && criteria.getNumberOfPhasers() > 2;
91 | }
92 | }
93 |
94 | @Test
95 | void shouldAllowToUseLambdaInMatcher() {
96 | //when
97 | int numberOfShips = ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
98 | //then
99 | assertThat(numberOfShips).isZero();
100 | //and
101 | verify(ts).findNumberOfShipsInRangeByCriteria(argLambda(c -> c.getMinimumRange() < 2000));
102 | }
103 |
104 | @Test
105 | void shouldAllowToUseLambdaInMatcherWithAdditionalDescription() {
106 | //when
107 | int numberOfShips = ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
108 | //then
109 | assertThat(numberOfShips).isZero();
110 | //and
111 | verify(ts).findNumberOfShipsInRangeByCriteria(argLambda(c -> c.getMinimumRange() < 2000, "minimum range closer than 2000"));
112 | }
113 |
114 | @Test
115 | void shouldAllowToUseLambdaWithMultipleConditionsInMatcher() {
116 | //when
117 | int numberOfShips = ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
118 | //then
119 | assertThat(numberOfShips).isZero();
120 | //and
121 | verify(ts).findNumberOfShipsInRangeByCriteria(argLambda(
122 | c -> c.getMinimumRange() < 2000 && c.getNumberOfPhasers() > 2,
123 | "ShipSearchCriteria minimumRange<2000 and numberOfPhasers>2"));
124 | }
125 |
126 | @Test
127 | void shouldKeepDescriptionInErrorMessage() {
128 | //given
129 | final String DESCRIPTION = "minimum range closer than 100";
130 | //when
131 | ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
132 | //then
133 | ThrowableAssert.ThrowingCallable verifyLambda = () -> {
134 | verify(ts).findNumberOfShipsInRangeByCriteria(argLambda(c -> c.getMinimumRange() < 100, DESCRIPTION));
135 | };
136 | assertThatThrownBy(verifyLambda)
137 | .isInstanceOf(AssertionError.class)
138 | .hasMessageContaining("Argument(s) are different! Wanted:\n" +
139 | "ts.findNumberOfShipsInRangeByCriteria(\n" +
140 | " " + DESCRIPTION + "\n" +
141 | ");")
142 | .hasMessageContaining("Actual invocation has different arguments:\n" +
143 | "ts.findNumberOfShipsInRangeByCriteria(\n" +
144 | " ShipSearchCriteria{minimumRange=1000, numberOfPhasers=4}\n" +
145 | ");");
146 |
147 | }
148 |
149 | @Test
150 | void shouldAcceptLambdaWhichMayThrowCheckedException() throws Exception {
151 | //when
152 | int numberOfShips = ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
153 | //then
154 | assertThat(numberOfShips).isZero();
155 | //and
156 | verify(ts).findNumberOfShipsInRangeByCriteria(argLambdaThrowing(methodDeclaringThrowingCheckedException()));
157 | }
158 |
159 | @Test
160 | void shouldPropagateCheckedExceptionIfThrownInLambda() throws Exception {
161 | //when
162 | int numberOfShips = ts.findNumberOfShipsInRangeByCriteria(searchCriteria);
163 | //then
164 | assertThat(numberOfShips).isZero();
165 | //and
166 | assertThatThrownBy(() -> verify(ts).findNumberOfShipsInRangeByCriteria(argLambdaThrowing(c -> {
167 | throw new IOException(UNEXPECTED_CHECKED_EXCEPTION_MESSAGE);
168 | })))
169 | .isInstanceOf(RuntimeException.class)
170 | .hasCauseInstanceOf(IOException.class)
171 | .hasMessage("java.io.IOException: " + UNEXPECTED_CHECKED_EXCEPTION_MESSAGE);
172 | }
173 |
174 | @SuppressWarnings("RedundantThrows")
175 | private ThrowingPredicate methodDeclaringThrowingCheckedException() throws Exception {
176 | return c -> c.getMinimumRange() < 2000 && c.getNumberOfPhasers() > 2;
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/src/test/java/info/solidsoft/mockito/java8/api/WithBDDMockitoTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Marcin Zajączkowski.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8.api;
7 |
8 | import info.solidsoft.mockito.java8.domain.TacticalStation;
9 | import org.junit.jupiter.api.Test;
10 |
11 | import java.io.BufferedWriter;
12 | import java.io.IOException;
13 |
14 | import static org.assertj.core.api.Assertions.assertThat;
15 | import static org.assertj.core.api.Assertions.assertThatThrownBy;
16 |
17 | class WithBDDMockitoTest implements WithBDDMockito {
18 |
19 | @Test
20 | void shouldAllowToCreateMockAndStubWithAnswerInClassicStyleWithoutStaticImports() {
21 | //given
22 | TacticalStation tsMock = mock(TacticalStation.class);
23 | given(tsMock.getNumberOfTubes()).willAnswer(i -> 3);
24 | //when
25 | int numberOfTubes = tsMock.getNumberOfTubes();
26 | //then
27 | assertThat(numberOfTubes).isEqualTo(3);
28 | }
29 |
30 | @Test
31 | void shouldVerifyMethodExecutionWithBasicMatcherWithoutStaticImports() {
32 | //given
33 | TacticalStation tsSpy = spy(TacticalStation.class);
34 | willDoNothing().given(tsSpy).fireTorpedo(anyInt());
35 | //when
36 | tsSpy.fireTorpedo(2);
37 | tsSpy.fireTorpedo(2);
38 | //then
39 | then(tsSpy).should(times(2)).fireTorpedo(2);
40 | }
41 |
42 | @Test //Issue #7
43 | void shouldProperlyCallVarargsMethod() throws IOException {
44 | //given
45 | BufferedWriter writerMock = mock(BufferedWriter.class);
46 | //when
47 | willThrow(new IOException()).given(writerMock).write(anyString());
48 | //then
49 | assertThatThrownBy(() -> writerMock.write("should throw IOException"))
50 | .isInstanceOf(IOException.class);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/test/java/info/solidsoft/mockito/java8/api/WithMockitoAndAdditionalMatchersTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Marcin Zajączkowski.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8.api;
7 |
8 | import info.solidsoft.mockito.java8.domain.TacticalStation;
9 | import org.junit.jupiter.api.Test;
10 |
11 | import static info.solidsoft.mockito.java8.domain.TacticalStation.TubeStatus.LOADED;
12 | import static org.assertj.core.api.Assertions.assertThat;
13 |
14 | class WithMockitoAndAdditionalMatchersTest implements WithBDDMockito, WithAdditionalMatchers {
15 |
16 | @Test
17 | void shouldAllowToCreateSpyStubAndVerifyWithMatcherWithoutStaticImports() {
18 | //given
19 | TacticalStation tsSpy = spy(TacticalStation.class);
20 | willDoNothing().given(tsSpy).fireTorpedo(lt(3));
21 | //when
22 | tsSpy.fireTorpedo(2);
23 | //then
24 | verify(tsSpy, atLeastOnce()).fireTorpedo(2);
25 | }
26 |
27 | @Test
28 | void shouldAllowToCreateMockAndStubWithoutStaticImports() {
29 | //given
30 | TacticalStation tsMock = mock(TacticalStation.class);
31 | given(tsMock.getTubeStatus(geq(2))).willReturn(LOADED);
32 | //when
33 | TacticalStation.TubeStatus numberOfTubes = tsMock.getTubeStatus(2);
34 | //then
35 | assertThat(numberOfTubes).isEqualTo(LOADED);
36 | }
37 |
38 | @Test
39 | void shouldVerifyMethodExecutionToAdditionalMatcherWithoutStaticImports() {
40 | //given
41 | TacticalStation tsSpy = spy(TacticalStation.class);
42 | willDoNothing().given(tsSpy).fireTorpedo(2);
43 | //when
44 | tsSpy.fireTorpedo(2);
45 | tsSpy.fireTorpedo(2);
46 | //then
47 | then(tsSpy).should(times(2)).fireTorpedo(and(gt(1), lt(3)));
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/test/java/info/solidsoft/mockito/java8/api/WithMockitoTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Marcin Zajączkowski.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8.api;
7 |
8 | import info.solidsoft.mockito.java8.domain.TacticalStation;
9 | import org.junit.jupiter.api.Test;
10 |
11 | import static org.assertj.core.api.Assertions.assertThat;
12 |
13 | class WithMockitoTest implements WithMockito {
14 |
15 | @Test
16 | void shouldVerifyMethodExecution() {
17 | //arrange
18 | TacticalStation tsSpy = spy(TacticalStation.class);
19 | doNothing().when(tsSpy).fireTorpedo(2);
20 | //act
21 | tsSpy.fireTorpedo(2);
22 | tsSpy.fireTorpedo(2);
23 | //assert
24 | verify(tsSpy, times(2)).fireTorpedo(2);
25 | }
26 |
27 | @Test
28 | void shouldAllowToCreateMockAndStubWithAnswerInClassicStyleWithoutStaticImports() {
29 | //arrange
30 | TacticalStation tsMock = mock(TacticalStation.class);
31 | when(tsMock.getNumberOfTubes()).thenAnswer(i -> 3);
32 | //act
33 | int numberOfTubes = tsMock.getNumberOfTubes();
34 | //assert
35 | assertThat(numberOfTubes).isEqualTo(3);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/test/java/info/solidsoft/mockito/java8/domain/ShipSearchCriteria.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Marcin Zajączkowski.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8.domain;
7 |
8 | /**
9 | * Test domain classes.
10 | */
11 | public class ShipSearchCriteria {
12 |
13 | private final int minimumRange;
14 | private final int numberOfPhasers;
15 |
16 | public ShipSearchCriteria(int minimumRange, int numberOfPhasers) {
17 | this.minimumRange = minimumRange;
18 | this.numberOfPhasers = numberOfPhasers;
19 | }
20 |
21 | public int getMinimumRange() {
22 | return minimumRange;
23 | }
24 |
25 | public int getNumberOfPhasers() {
26 | return numberOfPhasers;
27 | }
28 |
29 | @Override
30 | public String toString() {
31 | return "ShipSearchCriteria{" +
32 | "minimumRange=" + minimumRange +
33 | ", numberOfPhasers=" + numberOfPhasers +
34 | '}';
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/java/info/solidsoft/mockito/java8/domain/TacticalStation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Marcin Zajączkowski.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8.domain;
7 |
8 | /**
9 | * Test domain classes.
10 | */
11 | public class TacticalStation {
12 |
13 | public enum TubeStatus {
14 | EMPTY, LOADING, LOADED, UNLOADING, BROKEN
15 | }
16 |
17 | public int getNumberOfEnemyShipsInRange() {
18 | return 0;
19 | }
20 |
21 | public void fireTorpedo() {
22 | fireTorpedo(getNumberOfFirstLoadedTube());
23 | }
24 |
25 | public void fireTorpedo(int tubeNumber) {
26 | }
27 |
28 | private int getNumberOfFirstLoadedTube() {
29 | return 0;
30 | }
31 |
32 | public int getNumberOfTubes() {
33 | return 0;
34 | }
35 |
36 | public void reloadTubeWithGivenTorpedoType(int tubeNumber, TopedoType topedoType) {
37 | }
38 |
39 | public int getNumberOfRemainingTorpedos() {
40 | return 0;
41 | }
42 |
43 | public TubeStatus getTubeStatus(int tubeNumber) {
44 | return null;
45 | }
46 |
47 | public int smellyFindNumberOfShipsInRangeByCriteria(int minimumRange, String partOfName, int numberOfPhasers) {
48 | return 0;
49 | }
50 |
51 | public int findNumberOfShipsInRangeByCriteria(ShipSearchCriteria searchCriteria) {
52 | return 0;
53 | }
54 |
55 | public void firePhaser() {
56 | }
57 |
58 | public void doSelfCheck() {
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/test/java/info/solidsoft/mockito/java8/domain/TopedoType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Marcin Zajączkowski.
3 | *
4 | * Licensed under the Apache License, Version 2.0.
5 | */
6 | package info.solidsoft.mockito.java8.domain;
7 |
8 | /**
9 | * Test domain classes.
10 | */
11 | public enum TopedoType {
12 | PHOTON, CHRONITRON, PLASMA, QUANTUM
13 | }
14 |
--------------------------------------------------------------------------------