/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.internal;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import org.junit.After;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.StateMaster;
import org.mockito.exceptions.misusing.InvalidUseOfMatchersException;
import org.mockito.exceptions.misusing.UnfinishedStubbingException;
import org.mockito.exceptions.misusing.UnfinishedVerificationException;
import org.mockitousage.IMethods;
import org.mockitoutil.TestBase;
/**
* invalid state happens if:
*
* -unfinished stubbing
* -unfinished stubVoid
* -unfinished doReturn()
* -stubbing without actual method call
* -verify without actual method call
*
* we should aim to detect invalid state in following scenarios:
*
* -on method call on mock
* -on verify
* -on verifyZeroInteractions
* -on verifyNoMoreInteractions
* -on verify in order
* -on stub
* -on stubVoid
*/
@SuppressWarnings({"unchecked", "deprecation"})
public class InvalidStateDetectionTest extends TestBase {
@Mock private IMethods mock;
@After
public void resetState() {
super.resetState();
}
@Test
public void shouldDetectUnfinishedStubbing() {
when(mock.simpleMethod());
detectsAndCleansUp(new OnMethodCallOnMock(), UnfinishedStubbingException.class);
when(mock.simpleMethod());
detectsAndCleansUp(new OnStub(), UnfinishedStubbingException.class);
when(mock.simpleMethod());
detectsAndCleansUp(new OnStubVoid(), UnfinishedStubbingException.class);
when(mock.simpleMethod());
detectsAndCleansUp(new OnVerify(), UnfinishedStubbingException.class);
when(mock.simpleMethod());
detectsAndCleansUp(new OnVerifyInOrder(), UnfinishedStubbingException.class);
when(mock.simpleMethod());
detectsAndCleansUp(new OnVerifyZeroInteractions(), UnfinishedStubbingException.class);
when(mock.simpleMethod());
detectsAndCleansUp(new OnVerifyNoMoreInteractions(), UnfinishedStubbingException.class);
when(mock.simpleMethod());
detectsAndCleansUp(new OnDoAnswer(), UnfinishedStubbingException.class);
}
@Test
public void shouldDetectUnfinishedStubbingVoid() {
stubVoid(mock);
detectsAndCleansUp(new OnMethodCallOnMock(), UnfinishedStubbingException.class);
stubVoid(mock);
detectsAndCleansUp(new OnStub(), UnfinishedStubbingException.class);
stubVoid(mock);
detectsAndCleansUp(new OnStubVoid(), UnfinishedStubbingException.class);
stubVoid(mock);
detectsAndCleansUp(new OnVerify(), UnfinishedStubbingException.class);
stubVoid(mock);
detectsAndCleansUp(new OnVerifyInOrder(), UnfinishedStubbingException.class);
stubVoid(mock);
detectsAndCleansUp(new OnVerifyZeroInteractions(), UnfinishedStubbingException.class);
stubVoid(mock);
detectsAndCleansUp(new OnVerifyNoMoreInteractions(), UnfinishedStubbingException.class);
stubVoid(mock);
detectsAndCleansUp(new OnDoAnswer(), UnfinishedStubbingException.class);
}
@Test
public void shouldDetectUnfinishedDoAnswerStubbing() {
doAnswer(null);
detectsAndCleansUp(new OnMethodCallOnMock(), UnfinishedStubbingException.class);
doAnswer(null);
detectsAndCleansUp(new OnStub(), UnfinishedStubbingException.class);
doAnswer(null);
detectsAndCleansUp(new OnStubVoid(), UnfinishedStubbingException.class);
doAnswer(null);
detectsAndCleansUp(new OnVerify(), UnfinishedStubbingException.class);
doAnswer(null);
detectsAndCleansUp(new OnVerifyInOrder(), UnfinishedStubbingException.class);
doAnswer(null);
detectsAndCleansUp(new OnVerifyZeroInteractions(), UnfinishedStubbingException.class);
doAnswer(null);
detectsAndCleansUp(new OnVerifyNoMoreInteractions(), UnfinishedStubbingException.class);
doAnswer(null);
detectsAndCleansUp(new OnDoAnswer(), UnfinishedStubbingException.class);
}
@Test
public void shouldDetectUnfinishedVerification() {
verify(mock);
detectsAndCleansUp(new OnStub(), UnfinishedVerificationException.class);
verify(mock);
detectsAndCleansUp(new OnStubVoid(), UnfinishedVerificationException.class);
verify(mock);
detectsAndCleansUp(new OnVerify(), UnfinishedVerificationException.class);
verify(mock);
detectsAndCleansUp(new OnVerifyInOrder(), UnfinishedVerificationException.class);
verify(mock);
detectsAndCleansUp(new OnVerifyZeroInteractions(), UnfinishedVerificationException.class);
verify(mock);
detectsAndCleansUp(new OnVerifyNoMoreInteractions(), UnfinishedVerificationException.class);
verify(mock);
detectsAndCleansUp(new OnDoAnswer(), UnfinishedVerificationException.class);
}
@Test
public void shouldDetectMisplacedArgumentMatcher() {
anyObject();
detectsAndCleansUp(new OnStubVoid(), InvalidUseOfMatchersException.class);
anyObject();
detectsAndCleansUp(new OnVerify(), InvalidUseOfMatchersException.class);
anyObject();
detectsAndCleansUp(new OnVerifyInOrder(), InvalidUseOfMatchersException.class);
anyObject();
detectsAndCleansUp(new OnVerifyZeroInteractions(), InvalidUseOfMatchersException.class);
anyObject();
detectsAndCleansUp(new OnVerifyNoMoreInteractions(), InvalidUseOfMatchersException.class);
anyObject();
detectsAndCleansUp(new OnDoAnswer(), InvalidUseOfMatchersException.class);
}
@Test
public void shouldCorrectStateAfterDetectingUnfinishedStubbing() {
stubVoid(mock).toThrow(new RuntimeException());
try {
stubVoid(mock).toThrow(new RuntimeException()).on().oneArg(true);
fail();
} catch (UnfinishedStubbingException e) {}
stubVoid(mock).toThrow(new RuntimeException()).on().oneArg(true);
try {
mock.oneArg(true);
fail();
} catch (RuntimeException e) {}
}
@Test
public void shouldCorrectStateAfterDetectingUnfinishedVerification() {
mock.simpleMethod();
verify(mock);
try {
verify(mock).simpleMethod();
fail();
} catch (UnfinishedVerificationException e) {}
verify(mock).simpleMethod();
}
private interface DetectsInvalidState {
void detect(IMethods mock);
}
private static class OnVerify implements DetectsInvalidState {
public void detect(IMethods mock) {
verify(mock);
}
}
private static class OnVerifyInOrder implements DetectsInvalidState {
public void detect(IMethods mock) {
inOrder(mock).verify(mock);
}
}
private static class OnVerifyZeroInteractions implements DetectsInvalidState {
public void detect(IMethods mock) {
verifyZeroInteractions(mock);
}
}
private static class OnVerifyNoMoreInteractions implements DetectsInvalidState {
public void detect(IMethods mock) {
verifyNoMoreInteractions(mock);
}
}
private static class OnDoAnswer implements DetectsInvalidState {
public void detect(IMethods mock) {
doAnswer(null);
}
}
private static class OnStub implements DetectsInvalidState {
public void detect(IMethods mock) {
when(mock);
}
}
private static class OnStubVoid implements DetectsInvalidState {
public void detect(IMethods mock) {
stubVoid(mock);
}
}
private static class OnMethodCallOnMock implements DetectsInvalidState {
public void detect(IMethods mock) {
mock.simpleMethod();
}
}
private static class OnMockCreation implements DetectsInvalidState {
public void detect(IMethods mock) {
mock(IMethods.class);
}
}
private static class OnSpyCreation implements DetectsInvalidState {
public void detect(IMethods mock) {
spy(new Object());
}
}
private void detectsAndCleansUp(DetectsInvalidState detector, Class expected) {
try {
detector.detect(mock);
fail("Should throw an exception");
} catch (Exception e) {
assertEquals(expected, e.getClass());
}
//Make sure state is cleaned up
new StateMaster().validate();
}
}