| /* |
| * Copyright (c) 2007 Mockito contributors |
| * This program is made available under the terms of the MIT License. |
| */ |
| |
| package org.mockitousage.strictness; |
| |
| import org.assertj.core.api.Assertions; |
| import org.assertj.core.api.ThrowableAssert; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.mockito.Mock; |
| import org.mockito.Mockito; |
| import org.mockito.MockitoSession; |
| import org.mockito.exceptions.misusing.PotentialStubbingProblem; |
| import org.mockito.exceptions.misusing.UnnecessaryStubbingException; |
| import org.mockito.exceptions.verification.NoInteractionsWanted; |
| import org.mockito.quality.Strictness; |
| import org.mockitousage.IMethods; |
| import org.mockitoutil.TestBase; |
| |
| import static junit.framework.TestCase.assertFalse; |
| import static junit.framework.TestCase.assertTrue; |
| import static org.junit.Assert.assertNull; |
| import static org.mockito.BDDMockito.given; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.mockingDetails; |
| import static org.mockito.Mockito.verifyNoMoreInteractions; |
| import static org.mockito.Mockito.withSettings; |
| |
| //TODO 792 also move other Strictness tests to this package (unless they already have good package) |
| public class StrictnessPerMockTest { |
| |
| MockitoSession mockito; |
| @Mock IMethods strictStubsMock; |
| IMethods lenientMock; |
| |
| @Before |
| public void before() { |
| mockito = Mockito.mockitoSession().initMocks(this).strictness(Strictness.STRICT_STUBS).startMocking(); |
| assertNull(lenientMock); |
| lenientMock = mock(IMethods.class, withSettings().lenient()); |
| } |
| |
| @Test |
| public void knows_if_mock_is_lenient() { |
| assertTrue(mockingDetails(lenientMock).getMockCreationSettings().isLenient()); |
| assertFalse(mockingDetails(strictStubsMock).getMockCreationSettings().isLenient()); |
| } |
| |
| @Test |
| public void potential_stubbing_problem() { |
| //when |
| given(lenientMock.simpleMethod(100)).willReturn("100"); |
| given(strictStubsMock.simpleMethod(100)).willReturn("100"); |
| |
| //then on lenient mock (created by hand), we can call the stubbed method with different arg: |
| lenientMock.simpleMethod(200); |
| |
| //and on strict stub mock (created by session), we cannot call stubbed method with different arg: |
| Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() { |
| @Override |
| public void call() throws Throwable { |
| strictStubsMock.simpleMethod(200); |
| } |
| }).isInstanceOf(PotentialStubbingProblem.class); |
| } |
| |
| @Test |
| public void unnecessary_stubbing() { |
| //when |
| given(lenientMock.simpleMethod(100)).willReturn("100"); |
| given(strictStubsMock.simpleMethod(100)).willReturn("100"); |
| |
| //then unnecessary stubbing flags method only on the strict stub mock: |
| Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() { |
| @Override |
| public void call() throws Throwable { |
| mockito.finishMocking(); |
| } |
| }).isInstanceOf(UnnecessaryStubbingException.class) |
| .hasMessageContaining("1. -> ") |
| //good enough to prove that we're flagging just one unnecessary stubbing: |
| //TODO 792: let's make UnnecessaryStubbingException exception contain the Invocation instance |
| //so that we can write clean assertion rather than depending on string |
| .isNot(TestBase.hasMessageContaining("2. ->")); |
| } |
| |
| @Test |
| public void verify_no_more_invocations() { |
| //when |
| given(lenientMock.simpleMethod(100)).willReturn("100"); |
| given(strictStubsMock.simpleMethod(100)).willReturn("100"); |
| |
| //and: |
| strictStubsMock.simpleMethod(100); |
| lenientMock.simpleMethod(100); |
| |
| //then 'verifyNoMoreInteractions' ignores strict stub (implicitly verified) but flags the lenient mock |
| Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() { |
| @Override |
| public void call() throws Throwable { |
| verifyNoMoreInteractions(strictStubsMock, lenientMock); |
| } |
| }).isInstanceOf(NoInteractionsWanted.class) |
| .hasMessageContaining("But found this interaction on mock 'iMethods'") |
| //TODO 792: let's make NoInteractionsWanted exception contain the Invocation instances |
| //so that we can write clean assertion rather than depending on string |
| .hasMessageContaining("Actually, above is the only interaction with this mock"); |
| } |
| |
| @After |
| public void after() { |
| mockito.finishMocking(); |
| } |
| } |