blob: 935372426a60452ba65d2fe902d034bef0051437 [file] [log] [blame]
/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockitousage.stubbing;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import org.assertj.core.api.Assertions;
import org.assertj.core.api.ThrowableAssert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.exceptions.verification.NoInteractionsWanted;
import org.mockito.exceptions.verification.WantedButNotInvoked;
import org.mockitousage.IMethods;
import org.mockitoutil.TestBase;
@SuppressWarnings({ "serial", "unchecked", "rawtypes" })
public class StubbingWithThrowablesTest extends TestBase {
private LinkedList mock;
private Map mockTwo;
@Rule
public ExpectedException exception = ExpectedException.none();
@Before
public void setup() {
mock = mock(LinkedList.class);
mockTwo = mock(HashMap.class);
}
@Test
public void throws_same_exception_consecutively() {
when(mock.add("")).thenThrow(new ExceptionOne());
//1st invocation
Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
public void call() {
mock.add("");
}
}).isInstanceOf(ExceptionOne.class);
mock.add("1");
//2nd invocation
Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
public void call() {
mock.add("");
}
}).isInstanceOf(ExceptionOne.class);
}
@Test
public void throws_same_exception_consecutively_with_doThrow() {
doThrow(new ExceptionOne()).when(mock).clear();
//1st invocation
Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
public void call() {
mock.clear();
}
}).isInstanceOf(ExceptionOne.class);
mock.add("1");
//2nd invocation
Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
public void call() {
mock.clear();
}
}).isInstanceOf(ExceptionOne.class);
}
@Test
public void shouldStubWithThrowable() throws Exception {
IllegalArgumentException expected = new IllegalArgumentException("thrown by mock");
when(mock.add("throw")).thenThrow(expected);
exception.expect(sameInstance(expected));
mock.add("throw");
}
@Test
public void shouldSetThrowableToVoidMethod() throws Exception {
IllegalArgumentException expected = new IllegalArgumentException("thrown by mock");
doThrow(expected).when(mock).clear();
exception.expect(sameInstance(expected));
mock.clear();
}
@Test
public void shouldLastStubbingVoidBeImportant() throws Exception {
doThrow(new ExceptionOne()).when(mock).clear();
doThrow(new ExceptionTwo()).when(mock).clear();
exception.expect(ExceptionTwo.class);
mock.clear();
}
@Test
public void shouldFailStubbingThrowableOnTheSameInvocationDueToAcceptableLimitation() throws Exception {
when(mock.size()).thenThrow(new ExceptionOne());
exception.expect(ExceptionOne.class);
when(mock.size()).thenThrow(new ExceptionTwo());
}
@Test
public void shouldAllowSettingCheckedException() throws Exception {
Reader reader = mock(Reader.class);
IOException ioException = new IOException();
when(reader.read()).thenThrow(ioException);
exception.expect(sameInstance(ioException));
reader.read();
}
@Test
public void shouldAllowSettingError() throws Exception {
Error error = new Error();
when(mock.add("quake")).thenThrow(error);
exception.expect(Error.class);
mock.add("quake");
}
@Test
public void shouldNotAllowNullExceptionType() {
exception.expect(MockitoException.class);
exception.expectMessage("Cannot stub with null throwable");
when(mock.add(null)).thenThrow((Exception) null);
}
@Test
public void shouldInstantiateExceptionClassOnInteraction() {
when(mock.add(null)).thenThrow(NaughtyException.class);
exception.expect(NaughtyException.class);
mock.add(null);
}
@Test
public void shouldInstantiateExceptionClassWithOngoingStubbingOnInteraction() {
doThrow(NaughtyException.class).when(mock).add(null);
exception.expect(NaughtyException.class);
mock.add(null);
}
@Test
public void shouldNotAllowSettingInvalidCheckedException() {
exception.expect(MockitoException.class);
exception.expectMessage("Checked exception is invalid for this method");
when(mock.add("monkey island")).thenThrow(new Exception());
}
@Test
public void shouldNotAllowSettingNullThrowable() {
exception.expect(MockitoException.class);
exception.expectMessage("Cannot stub with null throwable");
when(mock.add("monkey island")).thenThrow((Throwable) null);
}
@Test
public void shouldNotAllowSettingNullThrowableArray() {
exception.expect(MockitoException.class);
exception.expectMessage("Cannot stub with null throwable");
when(mock.add("monkey island")).thenThrow((Throwable[]) null);
}
@Test
public void shouldNotAllowSettingNullThrowableClass() {
exception.expect(MockitoException.class);
exception.expectMessage("Exception type cannot be null");
when(mock.isEmpty()).thenThrow((Class) null);
}
@Test
public void shouldNotAllowSettingNullThrowableClasses() {
exception.expect(MockitoException.class);
exception.expectMessage("Exception type cannot be null");
when(mock.isEmpty()).thenThrow(RuntimeException.class, (Class[]) null);
}
@Test
public void shouldNotAllowSettingNullVarArgThrowableClass() {
exception.expect(MockitoException.class);
exception.expectMessage("Exception type cannot be null");
when(mock.isEmpty()).thenThrow(RuntimeException.class, (Class) null);
}
@Test
public void doThrowShouldNotAllowSettingNullThrowableClass() {
exception.expect(MockitoException.class);
exception.expectMessage("Exception type cannot be null");
doThrow((Class) null).when(mock).isEmpty();
}
@Test
public void doThrowShouldNotAllowSettingNullThrowableClasses() throws Exception {
exception.expect(MockitoException.class);
exception.expectMessage("Exception type cannot be null");
doThrow(RuntimeException.class, (Class) null).when(mock).isEmpty();
}
@Test
public void doThrowShouldNotAllowSettingNullVarArgThrowableClasses() throws Exception {
exception.expect(MockitoException.class);
exception.expectMessage("Exception type cannot be null");
doThrow(RuntimeException.class, (Class[]) null).when(mock).isEmpty();
}
@Test
public void shouldNotAllowSettingNullVarArgsThrowableClasses() throws Exception {
exception.expect(MockitoException.class);
exception.expectMessage("Exception type cannot be null");
when(mock.isEmpty()).thenThrow(RuntimeException.class, (Class<RuntimeException>[]) null);
}
@Test
public void shouldNotAllowDifferntCheckedException() throws Exception {
IMethods mock = mock(IMethods.class);
exception.expect(MockitoException.class);
exception.expectMessage("Checked exception is invalid for this method");
when(mock.throwsIOException(0)).thenThrow(CheckedException.class);
}
@Test
public void shouldNotAllowCheckedExceptionWhenErrorIsDeclared() throws Exception {
IMethods mock = mock(IMethods.class);
exception.expect(MockitoException.class);
exception.expectMessage("Checked exception is invalid for this method");
when(mock.throwsError(0)).thenThrow(CheckedException.class);
}
@Test
public void shouldNotAllowCheckedExceptionWhenNothingIsDeclared() throws Exception {
IMethods mock = mock(IMethods.class);
exception.expect(MockitoException.class);
exception.expectMessage("Checked exception is invalid for this method");
when(mock.throwsNothing(true)).thenThrow(CheckedException.class);
}
@Test
public void shouldMixThrowablesAndReturnsOnDifferentMocks() throws Exception {
when(mock.add("ExceptionOne")).thenThrow(new ExceptionOne());
when(mock.getLast()).thenReturn("last");
doThrow(new ExceptionTwo()).when(mock).clear();
doThrow(new ExceptionThree()).when(mockTwo).clear();
when(mockTwo.containsValue("ExceptionFour")).thenThrow(new ExceptionFour());
when(mockTwo.get("Are you there?")).thenReturn("Yes!");
assertNull(mockTwo.get("foo"));
assertTrue(mockTwo.keySet().isEmpty());
assertEquals("Yes!", mockTwo.get("Are you there?"));
try {
mockTwo.clear();
fail();
} catch (ExceptionThree e) {
}
try {
mockTwo.containsValue("ExceptionFour");
fail();
} catch (ExceptionFour e) {
}
assertNull(mock.getFirst());
assertEquals("last", mock.getLast());
try {
mock.add("ExceptionOne");
fail();
} catch (ExceptionOne e) {
}
try {
mock.clear();
fail();
} catch (ExceptionTwo e) {
}
}
@Test
public void shouldStubbingWithThrowableBeVerifiable() {
when(mock.size()).thenThrow(new RuntimeException());
doThrow(new RuntimeException()).when(mock).clone();
try {
mock.size();
fail();
} catch (RuntimeException e) {
}
try {
mock.clone();
fail();
} catch (RuntimeException e) {
}
verify(mock).size();
verify(mock).clone();
verifyNoMoreInteractions(mock);
}
@Test
public void shouldStubbingWithThrowableFailVerification() {
when(mock.size()).thenThrow(new RuntimeException());
doThrow(new RuntimeException()).when(mock).clone();
verifyZeroInteractions(mock);
mock.add("test");
try {
verify(mock).size();
fail();
} catch (WantedButNotInvoked e) {
}
try {
verify(mock).clone();
fail();
} catch (WantedButNotInvoked e) {
}
try {
verifyNoMoreInteractions(mock);
fail();
} catch (NoInteractionsWanted e) {
}
}
private class ExceptionOne extends RuntimeException {
}
private class ExceptionTwo extends RuntimeException {
}
private class ExceptionThree extends RuntimeException {
}
private class ExceptionFour extends RuntimeException {
}
private class CheckedException extends Exception {
}
public class NaughtyException extends RuntimeException {
public NaughtyException() {
throw new RuntimeException("boo!");
}
}
}