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 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 knows_if_mock_is_lenient()47 public void knows_if_mock_is_lenient() { 48 assertTrue(mockingDetails(lenientMock).getMockCreationSettings().isLenient()); 49 assertFalse(mockingDetails(strictStubsMock).getMockCreationSettings().isLenient()); 50 } 51 52 @Test potential_stubbing_problem()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 unnecessary_stubbing()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 verify_no_more_invocations()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 after()114 public void after() { 115 mockito.finishMocking(); 116 } 117 } 118