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