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