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