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