From 71cacff8c2f83884c31d9fd5ea2d67e4e1bb5a7f Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 4 Apr 2018 12:29:26 +0200 Subject: [PATCH] Upgrade to JUnit Jupiter 5.1 Issue: SPR-16408 --- build.gradle | 6 +- ...ndAfterMethodsSpringExtensionTestCase.java | 55 +++-- ...isterExtensionSpringExtensionTestCase.java | 220 ++++++++++++++++++ 3 files changed, 255 insertions(+), 26 deletions(-) create mode 100644 spring-test/src/test/java/org/springframework/test/context/junit/jupiter/RegisterExtensionSpringExtensionTestCase.java diff --git a/build.gradle b/build.gradle index 66d2d8d989e..cd4b629afc8 100644 --- a/build.gradle +++ b/build.gradle @@ -47,9 +47,9 @@ configure(allprojects) { project -> ext.hsqldbVersion = "2.4.0" ext.jackson2Version = "2.9.5" ext.jettyVersion = "9.4.9.v20180320" - ext.junitJupiterVersion = "5.0.3" - ext.junitPlatformVersion = "1.0.3" - ext.junitVintageVersion = "4.12.3" + ext.junitJupiterVersion = "5.1.0" + ext.junitPlatformVersion = "1.1.0" + ext.junitVintageVersion = "5.1.0" ext.kotlinVersion = "1.2.31" ext.log4jVersion = "2.11.0" ext.nettyVersion = "4.1.22.Final" diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/FailingBeforeAndAfterMethodsSpringExtensionTestCase.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/FailingBeforeAndAfterMethodsSpringExtensionTestCase.java index 6051b73b04e..d825d160bb2 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/FailingBeforeAndAfterMethodsSpringExtensionTestCase.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/FailingBeforeAndAfterMethodsSpringExtensionTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -76,15 +76,15 @@ class FailingBeforeAndAfterMethodsSpringExtensionTestCase { private static Stream> testClasses() { // @formatter:off return Stream.of( - AlwaysFailingBeforeTestClassTestCase.class, - AlwaysFailingAfterTestClassTestCase.class, - AlwaysFailingPrepareTestInstanceTestCase.class, - AlwaysFailingBeforeTestMethodTestCase.class, - AlwaysFailingBeforeTestExecutionTestCase.class, - AlwaysFailingAfterTestExecutionTestCase.class, - AlwaysFailingAfterTestMethodTestCase.class, - FailingBeforeTransactionTestCase.class, - FailingAfterTransactionTestCase.class); + AlwaysFailingBeforeTestClassTestKase.class, + AlwaysFailingAfterTestClassTestKase.class, + AlwaysFailingPrepareTestInstanceTestKase.class, + AlwaysFailingBeforeTestMethodTestKase.class, + AlwaysFailingBeforeTestExecutionTestKase.class, + AlwaysFailingAfterTestExecutionTestKase.class, + AlwaysFailingAfterTestMethodTestKase.class, + FailingBeforeTransactionTestKase.class, + FailingAfterTransactionTestKase.class); // @formatter:on } @@ -131,16 +131,16 @@ class FailingBeforeAndAfterMethodsSpringExtensionTestCase { } private int getExpectedStartedCount(Class testClass) { - return (testClass == AlwaysFailingBeforeTestClassTestCase.class ? 0 : 1); + return (testClass == AlwaysFailingBeforeTestClassTestKase.class ? 0 : 1); } private int getExpectedSucceededCount(Class testClass) { - return (testClass == AlwaysFailingAfterTestClassTestCase.class ? 1 : 0); + return (testClass == AlwaysFailingAfterTestClassTestKase.class ? 1 : 0); } private int getExpectedFailedCount(Class testClass) { - if (testClass == AlwaysFailingBeforeTestClassTestCase.class - || testClass == AlwaysFailingAfterTestClassTestCase.class) { + if (testClass == AlwaysFailingBeforeTestClassTestKase.class + || testClass == AlwaysFailingAfterTestClassTestKase.class) { return 0; } return 1; @@ -214,36 +214,44 @@ class FailingBeforeAndAfterMethodsSpringExtensionTestCase { } @TestExecutionListeners(AlwaysFailingBeforeTestClassTestExecutionListener.class) - private static class AlwaysFailingBeforeTestClassTestCase extends BaseTestCase { + // TestKase with a "K" so that it's not picked up by the suite or build + static class AlwaysFailingBeforeTestClassTestKase extends BaseTestCase { } @TestExecutionListeners(AlwaysFailingAfterTestClassTestExecutionListener.class) - private static class AlwaysFailingAfterTestClassTestCase extends BaseTestCase { + // TestKase with a "K" so that it's not picked up by the suite or build + static class AlwaysFailingAfterTestClassTestKase extends BaseTestCase { } @TestExecutionListeners(AlwaysFailingPrepareTestInstanceTestExecutionListener.class) - private static class AlwaysFailingPrepareTestInstanceTestCase extends BaseTestCase { + // TestKase with a "K" so that it's not picked up by the suite or build + static class AlwaysFailingPrepareTestInstanceTestKase extends BaseTestCase { } @TestExecutionListeners(AlwaysFailingBeforeTestMethodTestExecutionListener.class) - private static class AlwaysFailingBeforeTestMethodTestCase extends BaseTestCase { + // TestKase with a "K" so that it's not picked up by the suite or build + static class AlwaysFailingBeforeTestMethodTestKase extends BaseTestCase { } @TestExecutionListeners(AlwaysFailingBeforeTestExecutionTestExecutionListener.class) - private static class AlwaysFailingBeforeTestExecutionTestCase extends BaseTestCase { + // TestKase with a "K" so that it's not picked up by the suite or build + static class AlwaysFailingBeforeTestExecutionTestKase extends BaseTestCase { } @TestExecutionListeners(AlwaysFailingAfterTestExecutionTestExecutionListener.class) - private static class AlwaysFailingAfterTestExecutionTestCase extends BaseTestCase { + // TestKase with a "K" so that it's not picked up by the suite or build + static class AlwaysFailingAfterTestExecutionTestKase extends BaseTestCase { } @TestExecutionListeners(AlwaysFailingAfterTestMethodTestExecutionListener.class) - private static class AlwaysFailingAfterTestMethodTestCase extends BaseTestCase { + // TestKase with a "K" so that it's not picked up by the suite or build + static class AlwaysFailingAfterTestMethodTestKase extends BaseTestCase { } @SpringJUnitConfig(DatabaseConfig.class) @Transactional - private static class FailingBeforeTransactionTestCase { + // TestKase with a "K" so that it's not picked up by the suite or build + static class FailingBeforeTransactionTestKase { @Test void testNothing() { @@ -257,7 +265,8 @@ class FailingBeforeAndAfterMethodsSpringExtensionTestCase { @SpringJUnitConfig(DatabaseConfig.class) @Transactional - private static class FailingAfterTransactionTestCase { + // TestKase with a "K" so that it's not picked up by the suite or build + static class FailingAfterTransactionTestKase { @Test void testNothing() { diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/RegisterExtensionSpringExtensionTestCase.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/RegisterExtensionSpringExtensionTestCase.java new file mode 100644 index 00000000000..07a397c5f96 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/RegisterExtensionSpringExtensionTestCase.java @@ -0,0 +1,220 @@ +/* + * Copyright 2002-2018 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.junit.jupiter; + +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.TestReporter; +import org.junit.jupiter.api.extension.RegisterExtension; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.SpringJUnitJupiterTestSuite; +import org.springframework.test.context.junit.jupiter.comics.Cat; +import org.springframework.test.context.junit.jupiter.comics.Dog; +import org.springframework.test.context.junit.jupiter.comics.Person; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Integration tests which demonstrate that the Spring TestContext Framework can be used + * with JUnit Jupiter by registering the {@link SpringExtension} via a static field. + * Note, however, that this is not the recommended way to register the {@code SpringExtension}. + * + *

+ * To run these tests in an IDE that does not have built-in support for the JUnit + * Platform, simply run {@link SpringJUnitJupiterTestSuite} as a JUnit 4 test. + * + * @author Sam Brannen + * @since 5.1 + * @see SpringExtensionTestCase + * @see SpringExtension + * @see RegisterExtension + */ +@ContextConfiguration(classes = TestConfig.class) +@TestPropertySource(properties = "enigma = 42") +class RegisterExtensionSpringExtensionTestCase { + + @RegisterExtension + static final SpringExtension springExtension = new SpringExtension(); + + @Autowired + Person dilbert; + + @Autowired + List people; + + @Autowired + Dog dog; + + @Autowired + Cat cat; + + @Autowired + List cats; + + @Value("${enigma}") + Integer enigma; + + @Test + void applicationContextInjectedIntoMethod(ApplicationContext applicationContext) { + assertNotNull(applicationContext, + "ApplicationContext should have been injected by Spring"); + assertEquals(this.dilbert, applicationContext.getBean("dilbert", Person.class)); + } + + @Test + void genericApplicationContextInjectedIntoMethod( + GenericApplicationContext applicationContext) { + assertNotNull(applicationContext, + "GenericApplicationContext should have been injected by Spring"); + assertEquals(this.dilbert, applicationContext.getBean("dilbert", Person.class)); + } + + @Test + void autowiredFields() { + assertNotNull(this.dilbert, "Dilbert should have been @Autowired by Spring"); + assertEquals("Dilbert", this.dilbert.getName(), "Person's name"); + assertEquals(2, this.people.size(), "Number of people in context"); + + assertNotNull(this.dog, "Dogbert should have been @Autowired by Spring"); + assertEquals("Dogbert", this.dog.getName(), "Dog's name"); + + assertNotNull(this.cat, + "Catbert should have been @Autowired by Spring as the @Primary cat"); + assertEquals("Catbert", this.cat.getName(), "Primary cat's name"); + assertEquals(2, this.cats.size(), "Number of cats in context"); + + assertNotNull(this.enigma, + "Enigma should have been injected via @Value by Spring"); + assertEquals(Integer.valueOf(42), this.enigma, "enigma"); + } + + @Test + void autowiredParameterByTypeForSingleBean(@Autowired Dog dog) { + assertNotNull(dog, "Dogbert should have been @Autowired by Spring"); + assertEquals("Dogbert", dog.getName(), "Dog's name"); + } + + @Test + void autowiredParameterByTypeForPrimaryBean(@Autowired Cat primaryCat) { + assertNotNull(primaryCat, "Primary cat should have been @Autowired by Spring"); + assertEquals("Catbert", primaryCat.getName(), "Primary cat's name"); + } + + @Test + void autowiredParameterWithExplicitQualifier(@Qualifier("wally") Person person) { + assertNotNull(person, "Wally should have been @Autowired by Spring"); + assertEquals("Wally", person.getName(), "Person's name"); + } + + /** + * NOTE: Test code must be compiled with "-g" (debug symbols) or "-parameters" in + * order for the parameter name to be used as the qualifier; otherwise, use + * {@code @Qualifier("wally")}. + */ + @Test + void autowiredParameterWithImplicitQualifierBasedOnParameterName( + @Autowired Person wally) { + assertNotNull(wally, "Wally should have been @Autowired by Spring"); + assertEquals("Wally", wally.getName(), "Person's name"); + } + + @Test + void autowiredParameterAsJavaUtilOptional(@Autowired Optional dog) { + assertNotNull(dog, "Optional dog should have been @Autowired by Spring"); + assertTrue(dog.isPresent(), "Value of Optional should be 'present'"); + assertEquals("Dogbert", dog.get().getName(), "Dog's name"); + } + + @Test + void autowiredParameterThatDoesNotExistAsJavaUtilOptional( + @Autowired Optional number) { + assertNotNull(number, "Optional number should have been @Autowired by Spring"); + assertFalse(number.isPresent(), + "Value of Optional number should not be 'present'"); + } + + @Test + void autowiredParameterThatDoesNotExistButIsNotRequired( + @Autowired(required = false) Number number) { + assertNull(number, + "Non-required number should have been @Autowired as 'null' by Spring"); + } + + @Test + void autowiredParameterOfList(@Autowired List peopleParam) { + assertNotNull(peopleParam, + "list of people should have been @Autowired by Spring"); + assertEquals(2, peopleParam.size(), "Number of people in context"); + } + + @Test + void valueParameterWithPrimitiveType(@Value("99") int num) { + assertEquals(99, num); + } + + @Test + void valueParameterFromPropertyPlaceholder(@Value("${enigma}") Integer enigmaParam) { + assertNotNull(enigmaParam, + "Enigma should have been injected via @Value by Spring"); + assertEquals(Integer.valueOf(42), enigmaParam, "enigma"); + } + + @Test + void valueParameterFromDefaultValueForPropertyPlaceholder( + @Value("${bogus:false}") Boolean defaultValue) { + assertNotNull(defaultValue, + "Default value should have been injected via @Value by Spring"); + assertEquals(false, defaultValue, "default value"); + } + + @Test + void valueParameterFromSpelExpression(@Value("#{@dilbert.name}") String name) { + assertNotNull(name, + "Dilbert's name should have been injected via SpEL expression in @Value by Spring"); + assertEquals("Dilbert", name, "name from SpEL expression"); + } + + @Test + void valueParameterFromSpelExpressionWithNestedPropertyPlaceholder( + @Value("#{'Hello ' + ${enigma}}") String hello) { + assertNotNull(hello, + "hello should have been injected via SpEL expression in @Value by Spring"); + assertEquals("Hello 42", hello, "hello from SpEL expression"); + } + + @Test + void junitAndSpringMethodInjectionCombined(@Autowired Cat kittyCat, TestInfo testInfo, + ApplicationContext context, TestReporter testReporter) { + + assertNotNull(testInfo, "TestInfo should have been injected by JUnit"); + assertNotNull(testReporter, "TestReporter should have been injected by JUnit"); + + assertNotNull(context, "ApplicationContext should have been injected by Spring"); + assertNotNull(kittyCat, "Cat should have been @Autowired by Spring"); + } + +}