/* * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.test.context; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; import org.junit.Test; import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationConfigurationException; import org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener; import org.springframework.test.context.support.AbstractTestExecutionListener; import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; import org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener; import org.springframework.test.context.support.DirtiesContextTestExecutionListener; import org.springframework.test.context.transaction.TransactionalTestExecutionListener; import org.springframework.test.context.web.ServletTestExecutionListener; import static java.util.Arrays.*; import static java.util.stream.Collectors.*; import static org.junit.Assert.*; import static org.springframework.test.context.TestExecutionListeners.MergeMode.*; /** * Unit tests for the {@link TestExecutionListeners @TestExecutionListeners} * annotation, which verify: * <ul> * <li>Proper registering of {@linkplain TestExecutionListener listeners} in * conjunction with a {@link TestContextManager}</li> * <li><em>Inherited</em> functionality proposed in * <a href="https://jira.spring.io/browse/SPR-3896" target="_blank">SPR-3896</a></li> * </ul> * * @author Sam Brannen * @since 2.5 */ public class TestExecutionListenersTests { @Test public void defaultListeners() { List<Class<?>> expected = asList(ServletTestExecutionListener.class, DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class); assertRegisteredListeners(DefaultListenersTestCase.class, expected); } /** * @since 4.1 */ @Test public void defaultListenersMergedWithCustomListenerPrepended() { List<Class<?>> expected = asList(QuuxTestExecutionListener.class, ServletTestExecutionListener.class, DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class); assertRegisteredListeners(MergedDefaultListenersWithCustomListenerPrependedTestCase.class, expected); } /** * @since 4.1 */ @Test public void defaultListenersMergedWithCustomListenerAppended() { List<Class<?>> expected = asList(ServletTestExecutionListener.class, DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class, BazTestExecutionListener.class); assertRegisteredListeners(MergedDefaultListenersWithCustomListenerAppendedTestCase.class, expected); } /** * @since 4.1 */ @Test public void defaultListenersMergedWithCustomListenerInserted() { List<Class<?>> expected = asList(ServletTestExecutionListener.class, DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, BarTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class); assertRegisteredListeners(MergedDefaultListenersWithCustomListenerInsertedTestCase.class, expected); } @Test public void nonInheritedDefaultListeners() { assertRegisteredListeners(NonInheritedDefaultListenersTestCase.class, asList(QuuxTestExecutionListener.class)); } @Test public void inheritedDefaultListeners() { assertRegisteredListeners(InheritedDefaultListenersTestCase.class, asList(QuuxTestExecutionListener.class)); assertRegisteredListeners(SubInheritedDefaultListenersTestCase.class, asList(QuuxTestExecutionListener.class)); assertRegisteredListeners(SubSubInheritedDefaultListenersTestCase.class, asList(QuuxTestExecutionListener.class, EnigmaTestExecutionListener.class)); } @Test public void customListeners() { assertNumRegisteredListeners(ExplicitListenersTestCase.class, 3); } @Test public void customListenersDeclaredOnInterface() { assertRegisteredListeners(ExplicitListenersOnTestInterfaceTestCase.class, asList(FooTestExecutionListener.class, BarTestExecutionListener.class)); } @Test public void nonInheritedListeners() { assertNumRegisteredListeners(NonInheritedListenersTestCase.class, 1); } @Test public void inheritedListeners() { assertNumRegisteredListeners(InheritedListenersTestCase.class, 4); } @Test public void customListenersRegisteredViaMetaAnnotation() { assertNumRegisteredListeners(MetaTestCase.class, 3); } @Test public void nonInheritedListenersRegisteredViaMetaAnnotation() { assertNumRegisteredListeners(MetaNonInheritedListenersTestCase.class, 1); } @Test public void inheritedListenersRegisteredViaMetaAnnotation() { assertNumRegisteredListeners(MetaInheritedListenersTestCase.class, 4); } @Test public void customListenersRegisteredViaMetaAnnotationWithOverrides() { assertNumRegisteredListeners(MetaWithOverridesTestCase.class, 3); } @Test public void customsListenersRegisteredViaMetaAnnotationWithInheritedListenersWithOverrides() { assertNumRegisteredListeners(MetaInheritedListenersWithOverridesTestCase.class, 5); } @Test public void customListenersRegisteredViaMetaAnnotationWithNonInheritedListenersWithOverrides() { assertNumRegisteredListeners(MetaNonInheritedListenersWithOverridesTestCase.class, 8); } @Test(expected = AnnotationConfigurationException.class) public void listenersAndValueAttributesDeclared() { new TestContextManager(DuplicateListenersConfigTestCase.class); } private List<Class<?>> classes(TestContextManager testContextManager) { return testContextManager.getTestExecutionListeners().stream().map(Object::getClass).collect(toList()); } private List<String> names(List<Class<?>> classes) { return classes.stream().map(Class::getSimpleName).collect(toList()); } private void assertRegisteredListeners(Class<?> testClass, List<Class<?>> expected) { TestContextManager testContextManager = new TestContextManager(testClass); assertEquals("TELs registered for " + testClass.getSimpleName(), names(expected), names(classes(testContextManager))); } private void assertNumRegisteredListeners(Class<?> testClass, int expected) { TestContextManager testContextManager = new TestContextManager(testClass); assertEquals("Num registered TELs for " + testClass, expected, testContextManager.getTestExecutionListeners().size()); } // ------------------------------------------------------------------- static class DefaultListenersTestCase { } @TestExecutionListeners( listeners = {QuuxTestExecutionListener.class, DependencyInjectionTestExecutionListener.class}, mergeMode = MERGE_WITH_DEFAULTS) static class MergedDefaultListenersWithCustomListenerPrependedTestCase { } @TestExecutionListeners(listeners = BazTestExecutionListener.class, mergeMode = MERGE_WITH_DEFAULTS) static class MergedDefaultListenersWithCustomListenerAppendedTestCase { } @TestExecutionListeners(listeners = BarTestExecutionListener.class, mergeMode = MERGE_WITH_DEFAULTS) static class MergedDefaultListenersWithCustomListenerInsertedTestCase { } @TestExecutionListeners(QuuxTestExecutionListener.class) static class InheritedDefaultListenersTestCase extends DefaultListenersTestCase { } static class SubInheritedDefaultListenersTestCase extends InheritedDefaultListenersTestCase { } @TestExecutionListeners(EnigmaTestExecutionListener.class) static class SubSubInheritedDefaultListenersTestCase extends SubInheritedDefaultListenersTestCase { } @TestExecutionListeners(listeners = QuuxTestExecutionListener.class, inheritListeners = false) static class NonInheritedDefaultListenersTestCase extends InheritedDefaultListenersTestCase { } @TestExecutionListeners( {FooTestExecutionListener.class, BarTestExecutionListener.class, BazTestExecutionListener.class}) static class ExplicitListenersTestCase { } @TestExecutionListeners(QuuxTestExecutionListener.class) static class InheritedListenersTestCase extends ExplicitListenersTestCase { } @TestExecutionListeners(listeners = QuuxTestExecutionListener.class, inheritListeners = false) static class NonInheritedListenersTestCase extends InheritedListenersTestCase { } @TestExecutionListeners({ FooTestExecutionListener.class, BarTestExecutionListener.class }) interface ExplicitListenersTestInterface { } static class ExplicitListenersOnTestInterfaceTestCase implements ExplicitListenersTestInterface { } @TestExecutionListeners(listeners = FooTestExecutionListener.class, value = BarTestExecutionListener.class) static class DuplicateListenersConfigTestCase { } @TestExecutionListeners({ FooTestExecutionListener.class, BarTestExecutionListener.class, BazTestExecutionListener.class }) @Retention(RetentionPolicy.RUNTIME) @interface MetaListeners { } @TestExecutionListeners(QuuxTestExecutionListener.class) @Retention(RetentionPolicy.RUNTIME) @interface MetaInheritedListeners { } @TestExecutionListeners(listeners = QuuxTestExecutionListener.class, inheritListeners = false) @Retention(RetentionPolicy.RUNTIME) @interface MetaNonInheritedListeners { } @TestExecutionListeners @Retention(RetentionPolicy.RUNTIME) @interface MetaListenersWithOverrides { Class<? extends TestExecutionListener>[] listeners() default {FooTestExecutionListener.class, BarTestExecutionListener.class}; } @TestExecutionListeners @Retention(RetentionPolicy.RUNTIME) @interface MetaInheritedListenersWithOverrides { Class<? extends TestExecutionListener>[] listeners() default QuuxTestExecutionListener.class; boolean inheritListeners() default true; } @TestExecutionListeners @Retention(RetentionPolicy.RUNTIME) @interface MetaNonInheritedListenersWithOverrides { Class<? extends TestExecutionListener>[] listeners() default QuuxTestExecutionListener.class; boolean inheritListeners() default false; } @MetaListeners static class MetaTestCase { } @MetaInheritedListeners static class MetaInheritedListenersTestCase extends MetaTestCase { } @MetaNonInheritedListeners static class MetaNonInheritedListenersTestCase extends MetaInheritedListenersTestCase { } @MetaListenersWithOverrides(listeners = { FooTestExecutionListener.class, BarTestExecutionListener.class, BazTestExecutionListener.class }) static class MetaWithOverridesTestCase { } @MetaInheritedListenersWithOverrides(listeners = {FooTestExecutionListener.class, BarTestExecutionListener.class}) static class MetaInheritedListenersWithOverridesTestCase extends MetaWithOverridesTestCase { } @MetaNonInheritedListenersWithOverrides(listeners = { FooTestExecutionListener.class, BarTestExecutionListener.class, BazTestExecutionListener.class }, inheritListeners = true) static class MetaNonInheritedListenersWithOverridesTestCase extends MetaInheritedListenersWithOverridesTestCase { } static class FooTestExecutionListener extends AbstractTestExecutionListener { } static class BarTestExecutionListener extends AbstractTestExecutionListener { @Override public int getOrder() { // 2500 is between DependencyInjectionTestExecutionListener (2000) and // DirtiesContextTestExecutionListener (3000) return 2500; } } static class BazTestExecutionListener extends AbstractTestExecutionListener { @Override public int getOrder() { return Ordered.LOWEST_PRECEDENCE; } } static class QuuxTestExecutionListener extends AbstractTestExecutionListener { @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE; } } static class EnigmaTestExecutionListener extends AbstractTestExecutionListener { } }