Introduce support for JUnit 5 in the TestContext framework

This commit introduces initial support for JUnit Jupiter (i.e., the new
programming and extension models in JUnit 5) in the Spring TestContext
Framework.

Specifically, this commit introduces the following.

- SpringExtension: an implementation of multiple extension APIs from
  JUnit Jupiter that provides full support for the existing feature set
  of the Spring TestContext Framework. This support is enabled via
  @ExtendWith(SpringExtension.class).

- @SpringJUnitConfig: a composed annotation that combines
  @ExtendWith(SpringExtension.class) from JUnit Jupiter with
  @ContextConfiguration from the Spring TestContext Framework.

- @SpringJUnitWebConfig: a composed annotation that combines
  @ExtendWith(SpringExtension.class) from JUnit Jupiter with
  @ContextConfiguration and @WebAppConfiguration from the Spring
  TestContext Framework.

Issue: SPR-13575
This commit is contained in:
Sam Brannen
2016-07-04 21:39:09 +02:00
parent 54e3ea8d37
commit 873fc53a2f
29 changed files with 1812 additions and 1 deletions

View File

@@ -0,0 +1,40 @@
/*
* 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.junit;
import org.junit.platform.runner.IncludeEngines;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.runner.SelectPackages;
import org.junit.runner.RunWith;
/**
* JUnit 4 based test suite for tests that involve the Spring TestContext
* Framework and JUnit Jupiter (a.k.a., JUnit 5).
*
* <p>This class intentionally does not reside in the "jupiter" package
* so that the entire "jupiter" package can be excluded from the Gradle
* build. This class is therefore responsible for executing all JUnit
* Jupiter based tests in Spring's official test suite.
*
* @author Sam Brannen
* @since 5.0
*/
@RunWith(JUnitPlatform.class)
@IncludeEngines("junit-jupiter")
@SelectPackages("org.springframework.test.context.junit.jupiter")
public class SpringJUnitJupiterTestSuite {
}

View File

@@ -0,0 +1,75 @@
/*
* 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.junit.jupiter;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.SpringJUnitJupiterTestSuite;
import org.springframework.test.context.junit.jupiter.comics.Person;
import static org.junit.jupiter.api.Assertions.*;
/**
* Integration tests which demonstrate the composability of annotations from
* JUnit Jupiter and the Spring TestContext Framework.
*
* <p>Note that {@link SpringJUnitConfig @SpringJUnitConfig} is meta-annotated
* with JUnit Jupiter's {@link ExtendWith @ExtendWith} <b>and</b> Spring's
* {@link ContextConfiguration @ContextConfiguration}.
*
* <p>To run these tests in an IDE, simply run {@link SpringJUnitJupiterTestSuite}
* as a JUnit 4 test.
*
* @author Sam Brannen
* @since 5.0
* @see SpringExtension
* @see SpringJUnitConfig
* @see SpringExtensionTestCase
*/
@SpringJUnitConfig(TestConfig.class)
@DisplayName("@SpringJUnitConfig Tests")
class ComposedSpringExtensionTestCase {
@Autowired
Person dilbert;
@Autowired
List<Person> people;
@Test
@DisplayName("ApplicationContext injected into method")
void applicationContextInjected(ApplicationContext applicationContext) {
assertNotNull(applicationContext, "ApplicationContext should have been injected into method by Spring");
assertEquals(dilbert, applicationContext.getBean("dilbert", Person.class));
}
@Test
@DisplayName("Spring @Beans injected into fields")
void springBeansInjected() {
assertNotNull(dilbert, "Person should have been @Autowired by Spring");
assertEquals("Dilbert", dilbert.getName(), "Person's name");
assertEquals(2, people.size(), "Number of Person objects in context");
}
}

View File

@@ -0,0 +1,198 @@
/*
* 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.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.ExtendWith;
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 via the {@link SpringExtension}.
*
* <p>To run these tests in an IDE, simply run {@link SpringJUnitJupiterTestSuite}
* as a JUnit 4 test.
*
* @author Sam Brannen
* @since 5.0
* @see SpringExtension
* @see ComposedSpringExtensionTestCase
*/
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = TestConfig.class)
@TestPropertySource(properties = "enigma = 42")
class SpringExtensionTestCase {
@Autowired
Person dilbert;
@Autowired
List<Person> people;
@Autowired
Dog dog;
@Autowired
Cat cat;
@Autowired
List<Cat> 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(new Integer(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> 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> 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<Person> 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(new Integer(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");
}
}

View File

@@ -0,0 +1,83 @@
/*
* 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.junit.jupiter;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.SpringJUnitJupiterTestSuite;
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 support for {@link Autowired @Autowired}
* test class constructors with the Spring TestContext Framework and JUnit 5.
*
* <p>To run these tests in an IDE, simply run {@link SpringJUnitJupiterTestSuite}
* as a JUnit 4 test.
*
* @author Sam Brannen
* @since 5.0
* @see SpringExtension
* @see SpringJUnit5ConstructorInjectionTestCase
*/
@SpringJUnitConfig(TestConfig.class)
@TestPropertySource(properties = "enigma = 42")
class SpringJUnit5AutowiredConstructorInjectionTestCase {
final ApplicationContext applicationContext;
final Person dilbert;
final Dog dog;
final Integer enigma;
@Autowired
SpringJUnit5AutowiredConstructorInjectionTestCase(ApplicationContext applicationContext, Person dilbert, Dog dog,
@Value("${enigma}") Integer enigma) {
this.applicationContext = applicationContext;
this.dilbert = dilbert;
this.dog = dog;
this.enigma = enigma;
}
@Test
void applicationContextInjected() {
assertNotNull(applicationContext, "ApplicationContext should have been injected by Spring");
assertEquals(this.dilbert, applicationContext.getBean("dilbert", Person.class));
}
@Test
void beansInjected() {
assertNotNull(this.dilbert, "Dilbert should have been @Autowired by Spring");
assertEquals("Dilbert", this.dilbert.getName(), "Person's name");
assertNotNull(this.dog, "Dogbert should have been @Autowired by Spring");
assertEquals("Dogbert", this.dog.getName(), "Dog's name");
}
@Test
void propertyPlaceholderInjected() {
assertNotNull(this.enigma, "Enigma should have been injected via @Value by Spring");
assertEquals(new Integer(42), this.enigma, "enigma");
}
}

View File

@@ -0,0 +1,91 @@
/*
* 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.junit.jupiter;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.SpringJUnitJupiterTestSuite;
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 support for autowiring individual
* parameters in test class constructors using {@link Autowired @Autowired}
* and {@link Value @Value} with the Spring TestContext Framework and JUnit 5.
*
* <p>To run these tests in an IDE, simply run {@link SpringJUnitJupiterTestSuite}
* as a JUnit 4 test.
*
* @author Sam Brannen
* @since 5.0
* @see SpringExtension
* @see SpringJUnit5AutowiredConstructorInjectionTestCase
*/
@SpringJUnitConfig(TestConfig.class)
@TestPropertySource(properties = "enigma = 42")
class SpringJUnit5ConstructorInjectionTestCase {
final ApplicationContext applicationContext;
final Person dilbert;
final Dog dog;
final Integer enigma;
final TestInfo testInfo;
SpringJUnit5ConstructorInjectionTestCase(ApplicationContext applicationContext, @Autowired Person dilbert,
@Autowired Dog dog, @Value("${enigma}") Integer enigma, TestInfo testInfo) {
this.applicationContext = applicationContext;
this.dilbert = dilbert;
this.dog = dog;
this.enigma = enigma;
this.testInfo = testInfo;
}
@Test
void applicationContextInjected() {
assertNotNull(applicationContext, "ApplicationContext should have been injected by Spring");
assertEquals(this.dilbert, applicationContext.getBean("dilbert", Person.class));
}
@Test
void beansInjected() {
assertNotNull(this.dilbert, "Dilbert should have been @Autowired by Spring");
assertEquals("Dilbert", this.dilbert.getName(), "Person's name");
assertNotNull(this.dog, "Dogbert should have been @Autowired by Spring");
assertEquals("Dogbert", this.dog.getName(), "Dog's name");
}
@Test
void propertyPlaceholderInjected() {
assertNotNull(this.enigma, "Enigma should have been injected via @Value by Spring");
assertEquals(new Integer(42), this.enigma, "enigma");
}
@Test
void testInfoInjected() {
assertNotNull(this.testInfo, "TestInfo should have been injected by JUnit");
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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.junit.jupiter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
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;
/**
* Demo config for tests.
*
* @author Sam Brannen
* @since 5.0
*/
@Configuration
public class TestConfig {
@Bean
static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
Person dilbert() {
return new Person("Dilbert");
}
@Bean
Person wally() {
return new Person("Wally");
}
@Bean
Dog dogbert() {
return new Dog("Dogbert");
}
@Primary
@Bean
Cat catbert() {
return new Cat("Catbert");
}
@Bean
Cat garfield() {
return new Cat("Garfield");
}
}

View File

@@ -0,0 +1,31 @@
/*
* 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.junit.jupiter.comics;
/**
* Demo class for tests.
*
* @author Sam Brannen
* @since 5.0
*/
public class Cat extends Character {
public Cat(String name) {
super(name);
}
}

View File

@@ -0,0 +1,36 @@
/*
* 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.junit.jupiter.comics;
/**
* Demo class for tests.
*
* @author Sam Brannen
* @since 5.0
*/
public abstract class Character {
private final String name;
Character(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}

View File

@@ -0,0 +1,31 @@
/*
* 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.junit.jupiter.comics;
/**
* Demo class for tests.
*
* @author Sam Brannen
* @since 5.0
*/
public class Dog extends Character {
public Dog(String name) {
super(name);
}
}

View File

@@ -0,0 +1,31 @@
/*
* 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.junit.jupiter.comics;
/**
* Demo class for tests.
*
* @author Sam Brannen
* @since 5.0
*/
public class Person extends Character {
public Person(String name) {
super(name);
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.junit.jupiter.defaultmethods;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.comics.Cat;
/**
* Parameterized test class for integration tests that demonstrate support for
* interface default methods and Java generics in JUnit 5 test classes when used
* with the Spring TestContext Framework and the {@link SpringExtension}.
*
* @author Sam Brannen
* @since 5.0
*/
class CatInterfaceDefaultMethodsTestCase implements GenericComicCharactersInterfaceDefaultMethodsTestCase<Cat> {
@Override
public int getExpectedNumCharacters() {
return 2;
}
@Override
public String getExpectedName() {
return "Catbert";
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.junit.jupiter.defaultmethods;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.comics.Dog;
/**
* Parameterized test class for integration tests that demonstrate support for
* interface default methods and Java generics in JUnit 5 test classes when used
* with the Spring TestContext Framework and the {@link SpringExtension}.
*
* @author Sam Brannen
* @since 5.0
*/
class DogInterfaceDefaultMethodsTestCase implements GenericComicCharactersInterfaceDefaultMethodsTestCase<Dog> {
@Override
public int getExpectedNumCharacters() {
return 1;
}
@Override
public String getExpectedName() {
return "Dogbert";
}
}

View File

@@ -0,0 +1,57 @@
/*
* 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.junit.jupiter.defaultmethods;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.context.junit.jupiter.TestConfig;
import org.springframework.test.context.junit.jupiter.comics.Character;
import static org.junit.jupiter.api.Assertions.*;
/**
* Interface for integration tests that demonstrate support for interface default
* methods and Java generics in JUnit Jupiter test classes when used with the Spring
* TestContext Framework and the {@link SpringExtension}.
*
* @author Sam Brannen
* @since 5.0
*/
@SpringJUnitConfig(TestConfig.class)
interface GenericComicCharactersInterfaceDefaultMethodsTestCase<C extends Character> {
@Test
default void autowiredParameterWithParameterizedList(@Autowired List<C> characters) {
assertEquals(getExpectedNumCharacters(), characters.size(), "Number of characters in context");
}
@Test
default void autowiredParameterWithGenericBean(@Autowired C character) {
assertNotNull(character, "Character should have been @Autowired by Spring");
assertEquals(getExpectedName(), character.getName(), "character's name");
}
int getExpectedNumCharacters();
String getExpectedName();
}

View File

@@ -0,0 +1,42 @@
/*
* 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.junit.jupiter.generics;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.comics.Cat;
/**
* Parameterized test class for integration tests that demonstrate support for
* Java generics in JUnit 5 test classes when used with the Spring TestContext
* Framework and the {@link SpringExtension}.
*
* @author Sam Brannen
* @since 5.0
*/
class CatTestCase extends GenericComicCharactersTestCase<Cat> {
@Override
int getExpectedNumCharacters() {
return 2;
}
@Override
String getExpectedName() {
return "Catbert";
}
}

View File

@@ -0,0 +1,42 @@
/*
* 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.junit.jupiter.generics;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.comics.Dog;
/**
* Parameterized test class for integration tests that demonstrate support for
* Java generics in JUnit 5 test classes when used with the Spring TestContext
* Framework and the {@link SpringExtension}.
*
* @author Sam Brannen
* @since 5.0
*/
class DogTestCase extends GenericComicCharactersTestCase<Dog> {
@Override
int getExpectedNumCharacters() {
return 1;
}
@Override
String getExpectedName() {
return "Dogbert";
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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.junit.jupiter.generics;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.TestConfig;
import org.springframework.test.context.junit.jupiter.comics.Character;
import static org.junit.jupiter.api.Assertions.*;
/**
* Abstract base class for integration tests that demonstrate support for
* Java generics in JUnit 5 test classes when used with the Spring TestContext
* Framework and the {@link SpringExtension}.
*
* @author Sam Brannen
* @since 5.0
*/
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = TestConfig.class)
abstract class GenericComicCharactersTestCase<T extends Character> {
@Autowired
T character;
@Autowired
List<T> characters;
@Test
void autowiredFields() {
assertNotNull(this.character, "Character should have been @Autowired by Spring");
assertEquals(getExpectedName(), character.getName(), "character's name");
assertEquals(getExpectedNumCharacters(), this.characters.size(), "Number of characters in context");
}
@Test
void autowiredParameterByTypeForSingleGenericBean(@Autowired T character) {
assertNotNull(character, "Character should have been @Autowired by Spring");
assertEquals(getExpectedName(), character.getName(), "character's name");
}
abstract int getExpectedNumCharacters();
abstract String getExpectedName();
}

View File

@@ -0,0 +1,74 @@
/*
* 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.junit.jupiter.web;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.SpringJUnitJupiterTestSuite;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;
import static org.hamcrest.CoreMatchers.*;
import static org.springframework.http.MediaType.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;
/**
* Integration tests which demonstrate how to set up a {@link MockMvc}
* instance in an {@link BeforeEach @BeforeEach} method with the
* {@link SpringExtension} (registered via a custom
* {@link SpringJUnitWebConfig @SpringJUnitWebConfig} composed annotation).
*
* <p>To run these tests in an IDE, simply run {@link SpringJUnitJupiterTestSuite}
* as a JUnit 4 test.
*
* @author Sam Brannen
* @since 5.0
* @see SpringExtension
* @see SpringJUnitWebConfig
* @see org.springframework.test.context.junit.jupiter.web.WebSpringExtensionTestCase
*/
@SpringJUnitWebConfig(WebConfig.class)
class MultipleWebRequestsSpringExtensionTestCase {
MockMvc mockMvc;
@BeforeEach
void setUpMockMvc(WebApplicationContext wac) {
this.mockMvc = webAppContextSetup(wac)
.alwaysExpect(status().isOk())
.alwaysExpect(content().contentTypeCompatibleWith(APPLICATION_JSON))
.build();
}
@Test
void getPerson42() throws Exception {
this.mockMvc.perform(get("/person/42").accept(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.name", is("Dilbert")));
}
@Test
void getPerson99() throws Exception {
this.mockMvc.perform(get("/person/99").accept(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.name", is("Wally")));
}
}

View File

@@ -0,0 +1,39 @@
/*
* 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.junit.jupiter.web;
import org.springframework.test.context.junit.jupiter.comics.Person;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Sam Brannen
* @since 5.0
*/
@RestController
class PersonController {
@GetMapping("/person/{id}")
Person getPerson(@PathVariable long id) {
if (id == 42) {
return new Person("Dilbert");
}
return new Person("Wally");
}
}

View File

@@ -0,0 +1,36 @@
/*
* 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.junit.jupiter.web;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
/**
* @author Sam Brannen
* @since 5.0
*/
@Configuration
@EnableWebMvc
class WebConfig {
@Bean
PersonController personController() {
return new PersonController();
}
}

View File

@@ -0,0 +1,67 @@
/*
* 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.junit.jupiter.web;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.SpringJUnitJupiterTestSuite;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;
import static org.hamcrest.CoreMatchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;
/**
* Integration tests which demonstrate use of the Spring MVC Test Framework and
* the Spring TestContext Framework with JUnit Jupiter and the
* {@link SpringExtension} (via a custom
* {@link SpringJUnitWebConfig @SpringJUnitWebConfig} composed annotation).
*
* <p>Note how the {@link #springMvcTest(WebApplicationContext)} test method
* has the {@link WebApplicationContext} injected as a method parameter.
* This allows the {@link MockMvc} instance to be configured local to the
* test method without any fields in the test class.
*
* <p>To run these tests in an IDE, simply run {@link SpringJUnitJupiterTestSuite}
* as a JUnit 4 test.
*
* @author Sam Brannen
* @since 5.0
* @see SpringExtension
* @see SpringJUnitWebConfig
* @see org.springframework.test.context.junit.jupiter.web.MultipleWebRequestsSpringExtensionTestCase
* @see org.springframework.test.context.junit.jupiter.SpringExtensionTests
* @see org.springframework.test.context.junit.jupiter.ComposedSpringExtensionTests
*/
@SpringJUnitWebConfig(WebConfig.class)
@DisplayName("Web SpringExtension Tests")
class WebSpringExtensionTestCase {
@Test
void springMvcTest(WebApplicationContext wac) throws Exception {
webAppContextSetup(wac).build()
.perform(get("/person/42").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name", is("Dilbert")));
}
}