• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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