package org.mockitousage.junitrunner; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.exceptions.misusing.UnnecessaryStubbingException; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.mockito.junit.MockitoJUnitRunner; import org.mockitousage.IMethods; import org.mockitoutil.JUnitResultAssert; import org.mockitoutil.TestBase; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class StrictRunnerTest extends TestBase { JUnitCore runner = new JUnitCore(); @Test public void succeeds_when_all_stubs_were_used() { //when Result result = runner.run( StubbingInConstructorUsed.class, StubbingInBeforeUsed.class, StubbingInTestUsed.class ); //then JUnitResultAssert.assertThat(result).isSuccessful(); } @Test public void fails_when_stubs_were_not_used() { Class[] tests = {StubbingInConstructorUnused.class, StubbingInBeforeUnused.class, StubbingInTestUnused.class}; //when Result result = runner.run(tests); //then JUnitResultAssert.assertThat(result).fails(3, UnnecessaryStubbingException.class); } @Test public void does_not_report_unused_stubs_when_different_failure_is_present() { //when Result result = runner.run(WithUnrelatedAssertionFailure.class); //then JUnitResultAssert.assertThat(result).fails(1, MyAssertionError.class); } @Test public void runner_can_coexist_with_rule() { //I don't believe that this scenario is useful //I only wish that Mockito does not break awkwardly when both: runner & rule is used //when Result result = runner.run(RunnerAndRule.class); //then JUnitResultAssert.assertThat(result).fails(1, UnnecessaryStubbingException.class); } @Test public void runner_in_multi_threaded_tests() { //when Result result = runner.run(StubUsedFromDifferentThread.class); //then JUnitResultAssert.assertThat(result).isSuccessful(); } @RunWith(MockitoJUnitRunner.class) public static class StubbingInConstructorUsed extends StubbingInConstructorUnused { @Test public void test() { assertEquals("1", mock.simpleMethod(1)); } } @RunWith(MockitoJUnitRunner.Strict.class) //using Strict to make sure it does the right thing public static class StubbingInConstructorUnused { IMethods mock = when(mock(IMethods.class).simpleMethod(1)).thenReturn("1").getMock(); @Test public void dummy() {} } @RunWith(MockitoJUnitRunner.class) public static class StubbingInBeforeUsed extends StubbingInBeforeUnused { @Test public void test() { assertEquals("1", mock.simpleMethod(1)); } } @RunWith(MockitoJUnitRunner.class) public static class StubbingInBeforeUnused { @Mock IMethods mock; @Before public void before() { when(mock.simpleMethod(1)).thenReturn("1"); } @Test public void dummy() {} } @RunWith(MockitoJUnitRunner.class) public static class StubbingInTestUsed { @Test public void test() { IMethods mock = mock(IMethods.class); when(mock.simpleMethod(1)).thenReturn("1"); assertEquals("1", mock.simpleMethod(1)); } } @RunWith(MockitoJUnitRunner.class) public static class StubbingInTestUnused { @Test public void test() { IMethods mock = mock(IMethods.class); when(mock.simpleMethod(1)).thenReturn("1"); mock.simpleMethod(2); //different arg } } private static class MyAssertionError extends AssertionError {} @RunWith(MockitoJUnitRunner.class) public static class WithUnrelatedAssertionFailure { IMethods mock = mock(IMethods.class); IMethods mock2 = mock(IMethods.class); @Before public void before() { when(mock2.simpleMethod("unused stubbing")).thenReturn(""); } @Test public void passing_test() { when(mock.simpleMethod(1)).thenReturn("1"); assertEquals("1", mock.simpleMethod(1)); } @Test public void failing_test() { throw new MyAssertionError(); } } @RunWith(MockitoJUnitRunner.class) public static class RunnerAndRule { public @Rule MockitoRule rule = MockitoJUnit.rule(); IMethods mock = mock(IMethods.class); @Test public void passing_test() { when(mock.simpleMethod(1)).thenReturn("1"); mock.simpleMethod(2); } } @RunWith(MockitoJUnitRunner.class) public static class StubUsedFromDifferentThread { IMethods mock = mock(IMethods.class); @Test public void passing_test() throws Exception { //stubbing is done in main thread: when(mock.simpleMethod(1)).thenReturn("1"); //stubbing is used in a different thread //stubbing should not be reported as unused by the runner Thread t = new Thread() { public void run() { mock.simpleMethod(1); } }; t.start(); t.join(); } } }