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.stubbing; 7 8 import static org.junit.Assert.assertEquals; 9 import static org.junit.Assert.assertNull; 10 import static org.junit.Assert.assertTrue; 11 import static org.junit.Assert.fail; 12 import static org.hamcrest.CoreMatchers.sameInstance; 13 import static org.mockito.Mockito.doThrow; 14 import static org.mockito.Mockito.mock; 15 import static org.mockito.Mockito.verify; 16 import static org.mockito.Mockito.verifyNoMoreInteractions; 17 import static org.mockito.Mockito.verifyZeroInteractions; 18 import static org.mockito.Mockito.when; 19 20 import java.io.IOException; 21 import java.io.Reader; 22 import java.util.HashMap; 23 import java.util.LinkedList; 24 import java.util.Map; 25 26 import org.assertj.core.api.Assertions; 27 import org.assertj.core.api.ThrowableAssert; 28 import org.junit.Before; 29 import org.junit.Rule; 30 import org.junit.Test; 31 import org.junit.rules.ExpectedException; 32 import org.mockito.exceptions.base.MockitoException; 33 import org.mockito.exceptions.verification.NoInteractionsWanted; 34 import org.mockito.exceptions.verification.WantedButNotInvoked; 35 import org.mockitousage.IMethods; 36 import org.mockitoutil.TestBase; 37 38 @SuppressWarnings({ "serial", "unchecked", "rawtypes" }) 39 public class StubbingWithThrowablesTest extends TestBase { 40 41 private LinkedList mock; 42 43 private Map mockTwo; 44 45 @Rule 46 public ExpectedException exception = ExpectedException.none(); 47 48 @Before setup()49 public void setup() { 50 mock = mock(LinkedList.class); 51 mockTwo = mock(HashMap.class); 52 } 53 54 @Test throws_same_exception_consecutively()55 public void throws_same_exception_consecutively() { 56 when(mock.add("")).thenThrow(new ExceptionOne()); 57 58 //1st invocation 59 Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() { 60 public void call() { 61 mock.add(""); 62 } 63 }).isInstanceOf(ExceptionOne.class); 64 65 mock.add("1"); 66 67 //2nd invocation 68 Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() { 69 public void call() { 70 mock.add(""); 71 } 72 }).isInstanceOf(ExceptionOne.class); 73 } 74 75 @Test throws_same_exception_consecutively_with_doThrow()76 public void throws_same_exception_consecutively_with_doThrow() { 77 doThrow(new ExceptionOne()).when(mock).clear(); 78 79 //1st invocation 80 Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() { 81 public void call() { 82 mock.clear(); 83 } 84 }).isInstanceOf(ExceptionOne.class); 85 86 mock.add("1"); 87 88 //2nd invocation 89 Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() { 90 public void call() { 91 mock.clear(); 92 } 93 }).isInstanceOf(ExceptionOne.class); 94 } 95 96 @Test shouldStubWithThrowable()97 public void shouldStubWithThrowable() throws Exception { 98 IllegalArgumentException expected = new IllegalArgumentException("thrown by mock"); 99 when(mock.add("throw")).thenThrow(expected); 100 101 exception.expect(sameInstance(expected)); 102 mock.add("throw"); 103 } 104 105 @Test shouldSetThrowableToVoidMethod()106 public void shouldSetThrowableToVoidMethod() throws Exception { 107 IllegalArgumentException expected = new IllegalArgumentException("thrown by mock"); 108 109 doThrow(expected).when(mock).clear(); 110 111 exception.expect(sameInstance(expected)); 112 113 mock.clear(); 114 115 } 116 117 @Test shouldLastStubbingVoidBeImportant()118 public void shouldLastStubbingVoidBeImportant() throws Exception { 119 doThrow(new ExceptionOne()).when(mock).clear(); 120 doThrow(new ExceptionTwo()).when(mock).clear(); 121 122 exception.expect(ExceptionTwo.class); 123 124 mock.clear(); 125 } 126 127 @Test shouldFailStubbingThrowableOnTheSameInvocationDueToAcceptableLimitation()128 public void shouldFailStubbingThrowableOnTheSameInvocationDueToAcceptableLimitation() throws Exception { 129 when(mock.size()).thenThrow(new ExceptionOne()); 130 131 exception.expect(ExceptionOne.class); 132 133 when(mock.size()).thenThrow(new ExceptionTwo()); 134 } 135 136 @Test shouldAllowSettingCheckedException()137 public void shouldAllowSettingCheckedException() throws Exception { 138 Reader reader = mock(Reader.class); 139 IOException ioException = new IOException(); 140 141 when(reader.read()).thenThrow(ioException); 142 143 exception.expect(sameInstance(ioException)); 144 145 reader.read(); 146 } 147 148 @Test shouldAllowSettingError()149 public void shouldAllowSettingError() throws Exception { 150 Error error = new Error(); 151 152 when(mock.add("quake")).thenThrow(error); 153 154 exception.expect(Error.class); 155 156 mock.add("quake"); 157 } 158 159 @Test shouldNotAllowNullExceptionType()160 public void shouldNotAllowNullExceptionType() { 161 exception.expect(MockitoException.class); 162 exception.expectMessage("Cannot stub with null throwable"); 163 164 when(mock.add(null)).thenThrow((Exception) null); 165 } 166 167 @Test shouldInstantiateExceptionClassOnInteraction()168 public void shouldInstantiateExceptionClassOnInteraction() { 169 when(mock.add(null)).thenThrow(NaughtyException.class); 170 171 exception.expect(NaughtyException.class); 172 173 mock.add(null); 174 } 175 176 @Test shouldInstantiateExceptionClassWithOngoingStubbingOnInteraction()177 public void shouldInstantiateExceptionClassWithOngoingStubbingOnInteraction() { 178 doThrow(NaughtyException.class).when(mock).add(null); 179 180 exception.expect(NaughtyException.class); 181 182 mock.add(null); 183 } 184 185 @Test shouldNotAllowSettingInvalidCheckedException()186 public void shouldNotAllowSettingInvalidCheckedException() { 187 exception.expect(MockitoException.class); 188 exception.expectMessage("Checked exception is invalid for this method"); 189 190 when(mock.add("monkey island")).thenThrow(new Exception()); 191 } 192 193 @Test shouldNotAllowSettingNullThrowable()194 public void shouldNotAllowSettingNullThrowable() { 195 exception.expect(MockitoException.class); 196 exception.expectMessage("Cannot stub with null throwable"); 197 198 when(mock.add("monkey island")).thenThrow((Throwable) null); 199 } 200 201 @Test shouldNotAllowSettingNullThrowableArray()202 public void shouldNotAllowSettingNullThrowableArray() { 203 exception.expect(MockitoException.class); 204 exception.expectMessage("Cannot stub with null throwable"); 205 206 when(mock.add("monkey island")).thenThrow((Throwable[]) null); 207 } 208 209 @Test shouldNotAllowSettingNullThrowableClass()210 public void shouldNotAllowSettingNullThrowableClass() { 211 exception.expect(MockitoException.class); 212 exception.expectMessage("Exception type cannot be null"); 213 214 when(mock.isEmpty()).thenThrow((Class) null); 215 } 216 217 @Test shouldNotAllowSettingNullThrowableClasses()218 public void shouldNotAllowSettingNullThrowableClasses() { 219 exception.expect(MockitoException.class); 220 exception.expectMessage("Exception type cannot be null"); 221 222 when(mock.isEmpty()).thenThrow(RuntimeException.class, (Class[]) null); 223 } 224 225 @Test shouldNotAllowSettingNullVarArgThrowableClass()226 public void shouldNotAllowSettingNullVarArgThrowableClass() { 227 exception.expect(MockitoException.class); 228 exception.expectMessage("Exception type cannot be null"); 229 230 when(mock.isEmpty()).thenThrow(RuntimeException.class, (Class) null); 231 } 232 233 @Test doThrowShouldNotAllowSettingNullThrowableClass()234 public void doThrowShouldNotAllowSettingNullThrowableClass() { 235 exception.expect(MockitoException.class); 236 exception.expectMessage("Exception type cannot be null"); 237 238 doThrow((Class) null).when(mock).isEmpty(); 239 } 240 241 @Test doThrowShouldNotAllowSettingNullThrowableClasses()242 public void doThrowShouldNotAllowSettingNullThrowableClasses() throws Exception { 243 exception.expect(MockitoException.class); 244 exception.expectMessage("Exception type cannot be null"); 245 246 doThrow(RuntimeException.class, (Class) null).when(mock).isEmpty(); 247 } 248 249 @Test doThrowShouldNotAllowSettingNullVarArgThrowableClasses()250 public void doThrowShouldNotAllowSettingNullVarArgThrowableClasses() throws Exception { 251 exception.expect(MockitoException.class); 252 exception.expectMessage("Exception type cannot be null"); 253 254 doThrow(RuntimeException.class, (Class[]) null).when(mock).isEmpty(); 255 } 256 257 @Test shouldNotAllowSettingNullVarArgsThrowableClasses()258 public void shouldNotAllowSettingNullVarArgsThrowableClasses() throws Exception { 259 exception.expect(MockitoException.class); 260 exception.expectMessage("Exception type cannot be null"); 261 262 when(mock.isEmpty()).thenThrow(RuntimeException.class, (Class<RuntimeException>[]) null); 263 } 264 265 @Test shouldNotAllowDifferntCheckedException()266 public void shouldNotAllowDifferntCheckedException() throws Exception { 267 IMethods mock = mock(IMethods.class); 268 269 exception.expect(MockitoException.class); 270 exception.expectMessage("Checked exception is invalid for this method"); 271 272 when(mock.throwsIOException(0)).thenThrow(CheckedException.class); 273 } 274 275 @Test shouldNotAllowCheckedExceptionWhenErrorIsDeclared()276 public void shouldNotAllowCheckedExceptionWhenErrorIsDeclared() throws Exception { 277 IMethods mock = mock(IMethods.class); 278 279 exception.expect(MockitoException.class); 280 exception.expectMessage("Checked exception is invalid for this method"); 281 282 when(mock.throwsError(0)).thenThrow(CheckedException.class); 283 } 284 285 @Test shouldNotAllowCheckedExceptionWhenNothingIsDeclared()286 public void shouldNotAllowCheckedExceptionWhenNothingIsDeclared() throws Exception { 287 IMethods mock = mock(IMethods.class); 288 289 exception.expect(MockitoException.class); 290 exception.expectMessage("Checked exception is invalid for this method"); 291 292 when(mock.throwsNothing(true)).thenThrow(CheckedException.class); 293 } 294 295 @Test shouldMixThrowablesAndReturnsOnDifferentMocks()296 public void shouldMixThrowablesAndReturnsOnDifferentMocks() throws Exception { 297 when(mock.add("ExceptionOne")).thenThrow(new ExceptionOne()); 298 when(mock.getLast()).thenReturn("last"); 299 doThrow(new ExceptionTwo()).when(mock).clear(); 300 301 doThrow(new ExceptionThree()).when(mockTwo).clear(); 302 when(mockTwo.containsValue("ExceptionFour")).thenThrow(new ExceptionFour()); 303 when(mockTwo.get("Are you there?")).thenReturn("Yes!"); 304 305 assertNull(mockTwo.get("foo")); 306 assertTrue(mockTwo.keySet().isEmpty()); 307 assertEquals("Yes!", mockTwo.get("Are you there?")); 308 try { 309 mockTwo.clear(); 310 fail(); 311 } catch (ExceptionThree e) { 312 } 313 try { 314 mockTwo.containsValue("ExceptionFour"); 315 fail(); 316 } catch (ExceptionFour e) { 317 } 318 319 assertNull(mock.getFirst()); 320 assertEquals("last", mock.getLast()); 321 try { 322 mock.add("ExceptionOne"); 323 fail(); 324 } catch (ExceptionOne e) { 325 } 326 try { 327 mock.clear(); 328 fail(); 329 } catch (ExceptionTwo e) { 330 } 331 } 332 333 @Test shouldStubbingWithThrowableBeVerifiable()334 public void shouldStubbingWithThrowableBeVerifiable() { 335 when(mock.size()).thenThrow(new RuntimeException()); 336 doThrow(new RuntimeException()).when(mock).clone(); 337 338 try { 339 mock.size(); 340 fail(); 341 } catch (RuntimeException e) { 342 } 343 344 try { 345 mock.clone(); 346 fail(); 347 } catch (RuntimeException e) { 348 } 349 350 verify(mock).size(); 351 verify(mock).clone(); 352 verifyNoMoreInteractions(mock); 353 } 354 355 @Test shouldStubbingWithThrowableFailVerification()356 public void shouldStubbingWithThrowableFailVerification() { 357 when(mock.size()).thenThrow(new RuntimeException()); 358 doThrow(new RuntimeException()).when(mock).clone(); 359 360 verifyZeroInteractions(mock); 361 362 mock.add("test"); 363 364 try { 365 verify(mock).size(); 366 fail(); 367 } catch (WantedButNotInvoked e) { 368 } 369 370 try { 371 verify(mock).clone(); 372 fail(); 373 } catch (WantedButNotInvoked e) { 374 } 375 376 try { 377 verifyNoMoreInteractions(mock); 378 fail(); 379 } catch (NoInteractionsWanted e) { 380 } 381 } 382 383 private class ExceptionOne extends RuntimeException { 384 } 385 386 private class ExceptionTwo extends RuntimeException { 387 } 388 389 private class ExceptionThree extends RuntimeException { 390 } 391 392 private class ExceptionFour extends RuntimeException { 393 } 394 395 private class CheckedException extends Exception { 396 } 397 398 public class NaughtyException extends RuntimeException { NaughtyException()399 public NaughtyException() { 400 throw new RuntimeException("boo!"); 401 } 402 } 403 } 404