• 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.mockitousage.matchers;
7 
8 import org.assertj.core.api.Assertions;
9 import org.junit.Test;
10 import org.mockito.ArgumentCaptor;
11 import org.mockito.exceptions.base.MockitoException;
12 import org.mockito.exceptions.verification.WantedButNotInvoked;
13 import org.mockitousage.IMethods;
14 import org.mockitoutil.TestBase;
15 
16 import java.util.ArrayList;
17 import java.util.List;
18 
19 import static junit.framework.TestCase.*;
20 import static org.assertj.core.api.Assertions.assertThat;
21 import static org.mockito.Mockito.*;
22 
23 public class CapturingArgumentsTest extends TestBase {
24 
25     class Person {
26 
27         private final Integer age;
28 
Person(Integer age)29         public Person(Integer age) {
30             this.age = age;
31         }
32 
getAge()33         public int getAge() {
34             return age;
35         }
36     }
37 
38     class BulkEmailService {
39 
40         private EmailService service;
41 
BulkEmailService(EmailService service)42         public BulkEmailService(EmailService service) {
43             this.service = service;
44         }
45 
email(Integer .... personId)46         public void email(Integer ... personId) {
47             for (Integer i : personId) {
48                 Person person = new Person(i);
49                 service.sendEmailTo(person);
50             }
51         }
52     }
53 
54     interface EmailService {
sendEmailTo(Person person)55         boolean sendEmailTo(Person person);
56     }
57 
58     EmailService emailService = mock(EmailService.class);
59     BulkEmailService bulkEmailService = new BulkEmailService(emailService);
60     IMethods mock = mock(IMethods.class);
61 
62     @SuppressWarnings("deprecation")
63     @Test
should_allow_assertions_on_captured_argument()64     public void should_allow_assertions_on_captured_argument() {
65         //given
66         ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
67 
68         //when
69         bulkEmailService.email(12);
70 
71         //then
72         verify(emailService).sendEmailTo(argument.capture());
73         assertEquals(12, argument.getValue().getAge());
74     }
75 
76     @Test
should_allow_assertions_on_all_captured_arguments()77     public void should_allow_assertions_on_all_captured_arguments() {
78         //given
79         ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
80 
81         //when
82         bulkEmailService.email(11, 12);
83 
84         //then
85         verify(emailService, times(2)).sendEmailTo(argument.capture());
86         assertEquals(11, argument.getAllValues().get(0).getAge());
87         assertEquals(12, argument.getAllValues().get(1).getAge());
88     }
89 
90     @Test
should_allow_assertions_on_last_argument()91     public void should_allow_assertions_on_last_argument() {
92         //given
93         ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
94 
95         //when
96         bulkEmailService.email(11, 12, 13);
97 
98         //then
99         verify(emailService, times(3)).sendEmailTo(argument.capture());
100         assertEquals(13, argument.getValue().getAge());
101     }
102 
103     @Test
should_print_captor_matcher()104     public void should_print_captor_matcher() {
105         //given
106         ArgumentCaptor<Person> person = ArgumentCaptor.forClass(Person.class);
107 
108         try {
109             //when
110             verify(emailService).sendEmailTo(person.capture());
111             fail();
112         } catch(WantedButNotInvoked e) {
113             //then
114             assertThat(e).hasMessageContaining("<Capturing argument>");
115         }
116     }
117 
118     @Test
should_allow_assertions_on_captured_null()119     public void should_allow_assertions_on_captured_null() {
120         //given
121         ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
122 
123         //when
124         emailService.sendEmailTo(null);
125 
126         //then
127         verify(emailService).sendEmailTo(argument.capture());
128         assertEquals(null, argument.getValue());
129     }
130 
131     @Test
should_allow_construction_of_captor_for_parameterized_type_in_a_convenient_way()132     public void should_allow_construction_of_captor_for_parameterized_type_in_a_convenient_way()  {
133         //the test passes if this expression compiles
134         @SuppressWarnings("unchecked")
135         ArgumentCaptor<List<Person>> argument = ArgumentCaptor.forClass(List.class);
136         assertNotNull(argument);
137     }
138 
139     @Test
should_allow_construction_of_captor_for_a_more_specific_type()140     public void should_allow_construction_of_captor_for_a_more_specific_type()  {
141         //the test passes if this expression compiles
142         ArgumentCaptor<List<?>> argument = ArgumentCaptor.forClass(ArrayList.class);
143         assertNotNull(argument);
144     }
145 
146     @Test
should_allow_capturing_for_stubbing()147     public void should_allow_capturing_for_stubbing() {
148         //given
149         ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
150         when(emailService.sendEmailTo(argument.capture())).thenReturn(false);
151 
152         //when
153         emailService.sendEmailTo(new Person(10));
154 
155         //then
156         assertEquals(10, argument.getValue().getAge());
157     }
158 
159     @Test
should_capture_when_stubbing_only_when_entire_invocation_matches()160     public void should_capture_when_stubbing_only_when_entire_invocation_matches() {
161         //given
162         ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
163         when(mock.simpleMethod(argument.capture(), eq(2))).thenReturn("blah");
164 
165         //when
166         mock.simpleMethod("foo", 200);
167         mock.simpleMethod("bar", 2);
168 
169         //then
170         Assertions.assertThat(argument.getAllValues()).containsOnly("bar");
171     }
172 
173     @Test
should_say_something_smart_when_misused()174     public void should_say_something_smart_when_misused() {
175         ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
176         try {
177             argument.getValue();
178             fail();
179         } catch (MockitoException expected) { }
180     }
181 
182     @Test
should_capture_when_full_arg_list_matches()183     public void should_capture_when_full_arg_list_matches() throws Exception {
184         //given
185         ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
186 
187         //when
188         mock.simpleMethod("foo", 1);
189         mock.simpleMethod("bar", 2);
190 
191         //then
192         verify(mock).simpleMethod(captor.capture(), eq(1));
193         assertEquals(1, captor.getAllValues().size());
194         assertEquals("foo", captor.getValue());
195     }
196 
197     @Test
should_capture_int_by_creating_captor_with_primitive_wrapper()198     public void should_capture_int_by_creating_captor_with_primitive_wrapper() {
199         //given
200         ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
201 
202         //when
203         mock.intArgumentMethod(10);
204 
205         //then
206         verify(mock).intArgumentMethod(argument.capture());
207         assertEquals(10, (int) argument.getValue());
208     }
209 
210     @Test
should_capture_int_by_creating_captor_with_primitive()211     public void should_capture_int_by_creating_captor_with_primitive() throws Exception {
212         //given
213         ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(int.class);
214 
215         //when
216         mock.intArgumentMethod(10);
217 
218         //then
219         verify(mock).intArgumentMethod(argument.capture());
220         assertEquals(10, (int) argument.getValue());
221     }
222 
223     @Test
should_capture_byte_vararg_by_creating_captor_with_primitive()224     public void should_capture_byte_vararg_by_creating_captor_with_primitive() throws Exception {
225         // given
226         ArgumentCaptor<Byte> argumentCaptor = ArgumentCaptor.forClass(byte.class);
227 
228         // when
229         mock.varargsbyte((byte) 1, (byte) 2);
230 
231         // then
232         verify(mock).varargsbyte(argumentCaptor.capture());
233         assertEquals((byte) 2, (byte) argumentCaptor.getValue());
234         Assertions.assertThat(argumentCaptor.getAllValues()).containsExactly((byte) 1, (byte) 2);
235     }
236 
237     @Test
should_capture_byte_vararg_by_creating_captor_with_primitive_wrapper()238     public void should_capture_byte_vararg_by_creating_captor_with_primitive_wrapper() throws Exception {
239         // given
240         ArgumentCaptor<Byte> argumentCaptor = ArgumentCaptor.forClass(Byte.class);
241 
242         // when
243         mock.varargsbyte((byte) 1, (byte) 2);
244 
245         // then
246         verify(mock).varargsbyte(argumentCaptor.capture());
247         assertEquals((byte) 2, (byte) argumentCaptor.getValue());
248         Assertions.assertThat(argumentCaptor.getAllValues()).containsExactly((byte) 1, (byte) 2);
249     }
250 
251     @Test
should_capture_vararg()252     public void should_capture_vararg() throws Exception {
253         // given
254         ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
255 
256         // when
257         mock.mixedVarargs(42, "a", "b", "c");
258 
259         // then
260         verify(mock).mixedVarargs(any(), argumentCaptor.capture());
261         Assertions.assertThat(argumentCaptor.getAllValues()).containsExactly("a", "b", "c");
262     }
263 
264     @Test
should_capture_all_vararg()265     public void should_capture_all_vararg() throws Exception {
266         // given
267         ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
268 
269         // when
270         mock.mixedVarargs(42, "a", "b", "c");
271         mock.mixedVarargs(42, "again ?!");
272 
273         // then
274         verify(mock, times(2)).mixedVarargs(any(), argumentCaptor.capture());
275 
276         Assertions.assertThat(argumentCaptor.getAllValues()).containsExactly("a", "b", "c", "again ?!");
277     }
278 
279     @Test
should_capture_one_arg_even_when_using_vararg_captor_on_nonvararg_method()280     public void should_capture_one_arg_even_when_using_vararg_captor_on_nonvararg_method() throws Exception {
281         // given
282         ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
283 
284         // when
285         mock.simpleMethod("a", 2);
286 
287         // then
288         verify(mock).simpleMethod(argumentCaptor.capture(), eq(2));
289         Assertions.assertThat(argumentCaptor.getAllValues()).containsExactly("a");
290     }
291 
292     @Test
captures_correctly_when_captor_used_multiple_times()293     public void captures_correctly_when_captor_used_multiple_times() throws Exception {
294         // given
295         ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
296 
297         // when
298         mock.mixedVarargs(42, "a", "b", "c");
299 
300         // then
301         // this is only for backwards compatibility. It does not make sense in real to do so.
302         verify(mock).mixedVarargs(any(), argumentCaptor.capture(), argumentCaptor.capture(), argumentCaptor.capture());
303         Assertions.assertThat(argumentCaptor.getAllValues()).containsExactly("a", "b", "c");
304     }
305 
306     @Test
captures_correctly_when_captor_used_on_pure_vararg_method()307     public void captures_correctly_when_captor_used_on_pure_vararg_method() throws Exception {
308         // given
309         ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
310 
311         // when
312         mock.varargs(42, "capturedValue");
313 
314         // then
315         verify(mock).varargs(eq(42), argumentCaptor.capture());
316         Assertions.assertThat(argumentCaptor.getValue()).contains("capturedValue");
317     }
318 }
319