Home | History | Annotate | Download | only in strictness
      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.strictness;
      7 
      8 import org.assertj.core.api.Assertions;
      9 import org.assertj.core.api.ThrowableAssert;
     10 import org.junit.After;
     11 import org.junit.Before;
     12 import org.junit.Test;
     13 import org.mockito.Mock;
     14 import org.mockito.Mockito;
     15 import org.mockito.MockitoSession;
     16 import org.mockito.exceptions.misusing.PotentialStubbingProblem;
     17 import org.mockito.exceptions.misusing.UnnecessaryStubbingException;
     18 import org.mockito.exceptions.verification.NoInteractionsWanted;
     19 import org.mockito.quality.Strictness;
     20 import org.mockitousage.IMethods;
     21 import org.mockitoutil.TestBase;
     22 
     23 import static junit.framework.TestCase.assertFalse;
     24 import static junit.framework.TestCase.assertTrue;
     25 import static org.junit.Assert.assertNull;
     26 import static org.mockito.BDDMockito.given;
     27 import static org.mockito.Mockito.mock;
     28 import static org.mockito.Mockito.mockingDetails;
     29 import static org.mockito.Mockito.verifyNoMoreInteractions;
     30 import static org.mockito.Mockito.withSettings;
     31 
     32 //TODO 792 also move other Strictness tests to this package (unless they already have good package)
     33 public class StrictnessPerMockTest {
     34 
     35     MockitoSession mockito;
     36     @Mock IMethods strictStubsMock;
     37     IMethods lenientMock;
     38 
     39     @Before
     40     public void before() {
     41         mockito = Mockito.mockitoSession().initMocks(this).strictness(Strictness.STRICT_STUBS).startMocking();
     42         assertNull(lenientMock);
     43         lenientMock = mock(IMethods.class, withSettings().lenient());
     44     }
     45 
     46     @Test
     47     public void knows_if_mock_is_lenient() {
     48         assertTrue(mockingDetails(lenientMock).getMockCreationSettings().isLenient());
     49         assertFalse(mockingDetails(strictStubsMock).getMockCreationSettings().isLenient());
     50     }
     51 
     52     @Test
     53     public void potential_stubbing_problem() {
     54         //when
     55         given(lenientMock.simpleMethod(100)).willReturn("100");
     56         given(strictStubsMock.simpleMethod(100)).willReturn("100");
     57 
     58         //then on lenient mock (created by hand), we can call the stubbed method with different arg:
     59         lenientMock.simpleMethod(200);
     60 
     61         //and on strict stub mock (created by session), we cannot call stubbed method with different arg:
     62         Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
     63             @Override
     64             public void call() throws Throwable {
     65                 strictStubsMock.simpleMethod(200);
     66             }
     67         }).isInstanceOf(PotentialStubbingProblem.class);
     68     }
     69 
     70     @Test
     71     public void unnecessary_stubbing() {
     72         //when
     73         given(lenientMock.simpleMethod(100)).willReturn("100");
     74         given(strictStubsMock.simpleMethod(100)).willReturn("100");
     75 
     76         //then unnecessary stubbing flags method only on the strict stub mock:
     77         Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
     78             @Override
     79             public void call() throws Throwable {
     80                 mockito.finishMocking();
     81             }
     82         }).isInstanceOf(UnnecessaryStubbingException.class)
     83             .hasMessageContaining("1. -> ")
     84             //good enough to prove that we're flagging just one unnecessary stubbing:
     85             //TODO 792: let's make UnnecessaryStubbingException exception contain the Invocation instance
     86             //so that we can write clean assertion rather than depending on string
     87             .isNot(TestBase.hasMessageContaining("2. ->"));
     88     }
     89 
     90     @Test
     91     public void verify_no_more_invocations() {
     92         //when
     93         given(lenientMock.simpleMethod(100)).willReturn("100");
     94         given(strictStubsMock.simpleMethod(100)).willReturn("100");
     95 
     96         //and:
     97         strictStubsMock.simpleMethod(100);
     98         lenientMock.simpleMethod(100);
     99 
    100         //then 'verifyNoMoreInteractions' ignores strict stub (implicitly verified) but flags the lenient mock
    101         Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
    102             @Override
    103             public void call() throws Throwable {
    104                 verifyNoMoreInteractions(strictStubsMock, lenientMock);
    105             }
    106         }).isInstanceOf(NoInteractionsWanted.class)
    107             .hasMessageContaining("But found this interaction on mock 'iMethods'")
    108             //TODO 792: let's make NoInteractionsWanted exception contain the Invocation instances
    109             //so that we can write clean assertion rather than depending on string
    110             .hasMessageContaining("Actually, above is the only interaction with this mock");
    111     }
    112 
    113     @After
    114     public void after() {
    115         mockito.finishMocking();
    116     }
    117 }
    118