// Copyright © 2011-2013, Esko Luontola <www.orfjackal.net> // This software is released under the Apache License 2.0. // The license text is at http://www.apache.org/licenses/LICENSE-2.0 package fi.jumi.core.suite; import fi.jumi.api.drivers.*; import fi.jumi.core.api.*; import fi.jumi.core.drivers.DriverFinder; import fi.jumi.core.util.MethodCallSpy; import org.junit.Test; import java.util.*; import java.util.concurrent.Executor; import static fi.jumi.core.util.JumiMatchers.stackTrace; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; public class SuiteRunnerTest extends SuiteRunnerIntegrationHelper { private static final Class<?> CLASS_1 = DummyTest.class; private static final Class<?> CLASS_2 = SecondDummyTest.class; @Test public void runs_all_test_classes_which_are_found() { Driver anyDriver = mock(Driver.class); run(anyDriver, CLASS_1, CLASS_2); assertRunsTestClass(CLASS_1, anyDriver); assertRunsTestClass(CLASS_2, anyDriver); } @Test public void runs_each_test_class_using_its_own_driver() { Driver driverForClass1 = mock(Driver.class, "driver1"); Driver driverForClass2 = mock(Driver.class, "driver2"); run(new FakeDriverFinder() .map(CLASS_1, driverForClass1) .map(CLASS_2, driverForClass2), CLASS_1, CLASS_2); assertRunsTestClass(CLASS_1, driverForClass1); assertRunsTestClass(CLASS_2, driverForClass2); } private static void assertRunsTestClass(Class<?> testClass, Driver driverForAllClasses) { verify(driverForAllClasses).findTests(eq(testClass), any(SuiteNotifier.class), any(Executor.class)); } @Test public void removes_duplicate_onTestFound_events() { SuiteListener listener = mock(SuiteListener.class); run(listener, new Driver() { @Override public void findTests(Class<?> testClass, SuiteNotifier notifier, Executor executor) { notifier.fireTestFound(TestId.ROOT, "test name"); notifier.fireTestFound(TestId.ROOT, "test name"); } }, CLASS_1); verify(listener, times(1)).onTestFound(TestFile.fromClass(CLASS_1), TestId.ROOT, "test name"); } @Test public void notifies_when_all_test_classes_are_finished() { MethodCallSpy spy = new MethodCallSpy(); SuiteListener listener = spy.createProxyTo(SuiteListener.class); run(listener, new FakeTestClassDriver(), CLASS_1, CLASS_2); assertThat("should happen once", spy.countCallsTo("onSuiteFinished"), is(1)); assertThat("should happen last", spy.getLastCall(), is("onSuiteFinished")); } @Test public void reports_uncaught_exceptions_from_driver_threads_as_internal_errors() { SuiteListener listener = mock(SuiteListener.class); run(listener, new Driver() { @Override public void findTests(Class<?> testClass, SuiteNotifier notifier, Executor executor) { throw new RuntimeException("dummy exception from driver thread"); } }, CLASS_1); verify(listener).onInternalError( eq("Uncaught exception in thread " + Thread.currentThread().getName()), stackTrace("java.lang.RuntimeException: dummy exception from driver thread")); } @Test public void reports_uncaught_exceptions_from_test_threads_as_internal_errors() { SuiteListener listener = mock(SuiteListener.class); run(listener, new Driver() { @Override public void findTests(Class<?> testClass, SuiteNotifier notifier, Executor executor) { executor.execute(() -> { throw new RuntimeException("dummy exception from test thread"); }); } }, CLASS_1); verify(listener).onInternalError( eq("Uncaught exception in thread " + Thread.currentThread().getName()), stackTrace("java.lang.RuntimeException: dummy exception from test thread")); } // guinea pigs private static class DummyTest { } private static class SecondDummyTest { } public static class FakeTestClassDriver extends Driver { @Override public void findTests(Class<?> testClass, SuiteNotifier notifier, Executor executor) { notifier.fireTestFound(TestId.ROOT, testClass.getSimpleName()); notifier.fireTestStarted(TestId.ROOT) .fireTestFinished(); } } private static class FakeDriverFinder implements DriverFinder { private final Map<Class<?>, Driver> driverMapping = new HashMap<>(); @Override public Driver findTestClassDriver(Class<?> testClass) { Driver driver = driverMapping.get(testClass); if (driver == null) { throw new IllegalArgumentException("unexpected class: " + testClass); } return driver; } public FakeDriverFinder map(Class<?> testClass, Driver driver) { driverMapping.put(testClass, driver); return this; } } }