1 /*
2  * Copyright (c) 2017 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 package org.mockitousage.junitrunner;
6 
7 import org.junit.Before;
8 import org.junit.Rule;
9 import org.junit.Test;
10 import org.junit.runner.JUnitCore;
11 import org.junit.runner.Result;
12 import org.junit.runner.RunWith;
13 import org.mockito.Mock;
14 import org.mockito.exceptions.misusing.UnnecessaryStubbingException;
15 import org.mockito.junit.MockitoJUnit;
16 import org.mockito.junit.MockitoRule;
17 import org.mockito.junit.MockitoJUnitRunner;
18 import org.mockitousage.IMethods;
19 import org.mockitoutil.JUnitResultAssert;
20 import org.mockitoutil.TestBase;
21 
22 import static org.junit.Assert.assertEquals;
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.when;
25 
26 
27 public class StrictRunnerTest extends TestBase {
28 
29     JUnitCore runner = new JUnitCore();
30 
succeeds_when_all_stubs_were_used()31     @Test public void succeeds_when_all_stubs_were_used() {
32         //when
33         Result result = runner.run(
34                 StubbingInConstructorUsed.class,
35                 StubbingInBeforeUsed.class,
36                 StubbingInTestUsed.class
37         );
38         //then
39         JUnitResultAssert.assertThat(result).isSuccessful();
40     }
41 
fails_when_stubs_were_not_used()42     @Test public void fails_when_stubs_were_not_used() {
43         Class[] tests = {StubbingInConstructorUnused.class,
44                 StubbingInBeforeUnused.class,
45                 StubbingInTestUnused.class};
46 
47         //when
48         Result result = runner.run(tests);
49 
50         //then
51         JUnitResultAssert.assertThat(result).fails(3, UnnecessaryStubbingException.class);
52     }
53 
does_not_report_unused_stubs_when_different_failure_is_present()54     @Test public void does_not_report_unused_stubs_when_different_failure_is_present() {
55         //when
56         Result result = runner.run(WithUnrelatedAssertionFailure.class);
57 
58         //then
59         JUnitResultAssert.assertThat(result).fails(1, MyAssertionError.class);
60     }
61 
runner_can_coexist_with_rule()62     @Test public void runner_can_coexist_with_rule() {
63         //I don't believe that this scenario is useful
64         //I only wish that Mockito does not break awkwardly when both: runner & rule is used
65 
66         //when
67         Result result = runner.run(RunnerAndRule.class);
68 
69         //then
70         JUnitResultAssert.assertThat(result).fails(1, UnnecessaryStubbingException.class);
71     }
72 
runner_in_multi_threaded_tests()73     @Test public void runner_in_multi_threaded_tests() {
74         //when
75         Result result = runner.run(StubUsedFromDifferentThread.class);
76 
77         //then
78         JUnitResultAssert.assertThat(result).isSuccessful();
79     }
80 
81     @RunWith(MockitoJUnitRunner.class)
82     public static class StubbingInConstructorUsed extends StubbingInConstructorUnused {
test()83         @Test public void test() {
84             assertEquals("1", mock.simpleMethod(1));
85         }
86     }
87 
88     @RunWith(MockitoJUnitRunner.Strict.class) //using Strict to make sure it does the right thing
89     public static class StubbingInConstructorUnused {
90         IMethods mock = when(mock(IMethods.class).simpleMethod(1)).thenReturn("1").getMock();
dummy()91         @Test public void dummy() {}
92     }
93 
94     @RunWith(MockitoJUnitRunner.class)
95     public static class StubbingInBeforeUsed extends StubbingInBeforeUnused {
test()96         @Test public void test() {
97             assertEquals("1", mock.simpleMethod(1));
98         }
99     }
100 
101     @RunWith(MockitoJUnitRunner.class)
102     public static class StubbingInBeforeUnused {
103         @Mock IMethods mock;
before()104         @Before public void before() {
105             when(mock.simpleMethod(1)).thenReturn("1");
106         }
dummy()107         @Test public void dummy() {}
108     }
109 
110     @RunWith(MockitoJUnitRunner.class)
111     public static class StubbingInTestUsed {
test()112         @Test public void test() {
113             IMethods mock = mock(IMethods.class);
114             when(mock.simpleMethod(1)).thenReturn("1");
115             assertEquals("1", mock.simpleMethod(1));
116         }
117     }
118 
119     @RunWith(MockitoJUnitRunner.class)
120     public static class StubbingInTestUnused {
test()121         @Test public void test() {
122             IMethods mock = mock(IMethods.class);
123             when(mock.simpleMethod(1)).thenReturn("1");
124             mock.simpleMethod(2); //different arg
125         }
126     }
127 
128     private static class MyAssertionError extends AssertionError {}
129 
130     @RunWith(MockitoJUnitRunner.class)
131     public static class WithUnrelatedAssertionFailure {
132 
133         IMethods mock = mock(IMethods.class);
134         IMethods mock2 = mock(IMethods.class);
135 
before()136         @Before public void before() {
137             when(mock2.simpleMethod("unused stubbing")).thenReturn("");
138         }
139 
passing_test()140         @Test public void passing_test() {
141             when(mock.simpleMethod(1)).thenReturn("1");
142             assertEquals("1", mock.simpleMethod(1));
143         }
144 
failing_test()145         @Test public void failing_test() {
146             throw new MyAssertionError();
147         }
148     }
149 
150     @RunWith(MockitoJUnitRunner.class)
151     public static class RunnerAndRule {
152 
153         public @Rule MockitoRule rule = MockitoJUnit.rule();
154         IMethods mock = mock(IMethods.class);
155 
passing_test()156         @Test public void passing_test() {
157             when(mock.simpleMethod(1)).thenReturn("1");
158             mock.simpleMethod(2);
159         }
160     }
161 
162     @RunWith(MockitoJUnitRunner.class)
163     public static class StubUsedFromDifferentThread {
164 
165         IMethods mock = mock(IMethods.class);
166 
passing_test()167         @Test public void passing_test() throws Exception {
168             //stubbing is done in main thread:
169             when(mock.simpleMethod(1)).thenReturn("1");
170 
171             //stubbing is used in a different thread
172             //stubbing should not be reported as unused by the runner
173             Thread t = new Thread() {
174                 public void run() {
175                     mock.simpleMethod(1);
176                 }
177             };
178             t.start();
179             t.join();
180         }
181     }
182 }
183