├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
├── main
└── java
│ └── org
│ └── springframework
│ └── test
│ └── context
│ └── junit
│ └── jupiter
│ ├── MethodParameterFactory.java
│ ├── ParameterAutowireUtils.java
│ ├── SpringExtension.java
│ ├── SpringJUnitJupiterConfig.java
│ └── web
│ └── SpringJUnitJupiterWebConfig.java
└── test
├── java
└── org
│ └── springframework
│ └── test
│ └── context
│ └── junit
│ └── jupiter
│ ├── ComposedSpringExtensionTests.java
│ ├── SpringExtensionTestSuite.java
│ ├── SpringExtensionTests.java
│ ├── SpringJUnit5AutowiredConstructorInjectionTests.java
│ ├── SpringJUnit5ConstructorInjectionTests.java
│ ├── TestConfig.java
│ ├── comics
│ ├── Cat.java
│ ├── Character.java
│ ├── Dog.java
│ └── Person.java
│ ├── defaultmethods
│ ├── CatInterfaceDefaultMethodsTests.java
│ ├── DogInterfaceDefaultMethodsTests.java
│ └── GenericComicCharactersInterfaceDefaultMethodsTests.java
│ ├── generics
│ ├── CatTests.java
│ ├── DogTests.java
│ └── GenericComicCharactersTests.java
│ ├── web
│ ├── MultipleWebRequestsSpringExtensionTests.java
│ ├── PersonController.java
│ ├── WebConfig.java
│ └── WebSpringExtensionTests.java
│ └── xml
│ └── XmlSpringExtensionTests.java
└── resources
├── log4j2-test.xml
└── test-config.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Gradle
2 | .gradle
3 | build/
4 |
5 | # Ignore Gradle GUI config
6 | gradle-app.setting
7 |
8 | # Eclipse
9 | /.classpath
10 | /.settings/
11 | /.project
12 | /bin/
13 |
14 | # IntelliJ
15 | .idea
16 | *.iml
17 | *.ipr
18 | *.iws
19 |
20 | # Misc
21 | *.log
22 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 |
3 | jdk:
4 | - oraclejdk8
5 |
6 | before_cache:
7 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
8 |
9 | cache:
10 | directories:
11 | - $HOME/.gradle/caches/
12 | - $HOME/.gradle/wrapper/
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Spring JUnit 5 Testing Support
2 |
3 | This project served as the official prototype for [JUnit 5][] testing support
4 | in the [Spring TestContext Framework][] and has been incorporated into
5 | [Spring Framework][] 5.0 in conjunction with [SPR-13575][]. Consequently, no
6 | further work is planned in this repository in terms of new features: new
7 | features are only supported in Spring Framework 5.0+. Note, however, that this
8 | project can in fact be used for JUnit Jupiter testing support in conjunction
9 | with Spring Framework 4.3.x.
10 |
11 | # Using the `SpringExtension`
12 |
13 | Currently, all that's needed to use the _Spring TestContext Framework_ with JUnit 5
14 | is to annotate a JUnit Jupiter based test class with `@ExtendWith(SpringExtension.class)`
15 | and whatever Spring annotations you need (e.g., `@ContextConfiguration`, `@Transactional`,
16 | `@Sql`, etc.), but make sure you use `@Test`, `@BeforeEach`, etc. from the appropriate
17 | `org.junit.jupiter.api` package. See [`SpringExtensionTests`] for an example of this
18 | extension in action, and check out the source code of [`SpringExtension`] if you're
19 | interested in the implementation details.
20 |
21 | ## Composing Annotations from Spring & JUnit
22 |
23 | Spring has supported [composed annotations] for several years now, and as of JUnit 5
24 | annotations in JUnit can also be used as meta-annotations. We can therefore create
25 | custom annotations that are composed from Spring annotations **and** JUnit 5
26 | annotations. Take a look at [`@SpringJUnitJupiterConfig`] for an example, and check out
27 | [`ComposedSpringExtensionTests`] for an example of `@SpringJUnitJupiterConfig` in action.
28 |
29 | # License
30 |
31 | This project is released under version 2.0 of the [Apache License][].
32 |
33 | # Artifacts
34 |
35 | There are currently no downloadable artifacts for this project; however,
36 | you may opt to install `spring-test-junit5` in your local Maven repository
37 | or include a dependency on `spring-test-junit5` via JitPack. See the following
38 | sections for further details.
39 |
40 | ## Local Maven Installation
41 |
42 | If you install in a local Maven repository (see below)
43 | the generated artifact will correspond to the following.
44 |
45 | - **Group ID**: `org.springframework.test`
46 | - **Artifact ID**: `spring-test-junit5`
47 | - **Version**: `1.0.0.BUILD-SNAPSHOT`
48 |
49 | ## JitPack
50 |
51 | If you'd like to build against a release tag for `spring-test-junit5`, you
52 | may be interested in using [JitPack][]. For example, to build against the
53 | `1.5.0` tag, the following Maven coordinates will work.
54 |
55 | - **Group ID**: `com.github.sbrannen`
56 | - **Artifact ID**: `spring-test-junit5`
57 | - **Version**: `1.5.0`
58 |
59 | ### JitPack with Gradle
60 |
61 | ```groovy
62 | repositories {
63 | mavenCentral()
64 | maven { url 'https://jitpack.io' }
65 | }
66 |
67 | // ...
68 |
69 | dependencies {
70 | // ...
71 | testCompile('com.github.sbrannen:spring-test-junit5:1.5.0')
72 | // ...
73 | }
74 | ```
75 |
76 | ### JitPack with Maven
77 |
78 | ```xml
79 |
Supports parameters declared in methods and constructors. 49 | * @param parameter the parameter to create a {@code MethodParameter} for; 50 | * never {@code null} 51 | * @return a new {@code MethodParameter} 52 | * @see #createSynthesizingMethodParameter(Parameter) 53 | */ 54 | public static MethodParameter createMethodParameter(Parameter parameter) { 55 | Assert.notNull(parameter, "Parameter must not be null"); 56 | Executable executable = parameter.getDeclaringExecutable(); 57 | if (executable instanceof Method) { 58 | return new MethodParameter((Method) executable, getIndex(parameter)); 59 | } 60 | // else 61 | return new MethodParameter((Constructor>) executable, getIndex(parameter)); 62 | } 63 | 64 | /** 65 | * Create a {@link SynthesizingMethodParameter} from the supplied {@link Parameter}. 66 | *
Supports parameters declared in methods. 67 | * @param parameter the parameter to create a {@code SynthesizingMethodParameter} 68 | * for; never {@code null} 69 | * @return a new {@code SynthesizingMethodParameter} 70 | * @throws UnsupportedOperationException if the supplied parameter is declared 71 | * in a constructor 72 | * @see #createMethodParameter(Parameter) 73 | */ 74 | public static SynthesizingMethodParameter createSynthesizingMethodParameter(Parameter parameter) { 75 | Assert.notNull(parameter, "Parameter must not be null"); 76 | Executable executable = parameter.getDeclaringExecutable(); 77 | if (executable instanceof Method) { 78 | return new SynthesizingMethodParameter((Method) executable, getIndex(parameter)); 79 | } 80 | // else 81 | throw new UnsupportedOperationException( 82 | "Cannot create a SynthesizingMethodParameter for a constructor parameter: " + parameter); 83 | } 84 | 85 | private static int getIndex(Parameter parameter) { 86 | Assert.notNull(parameter, "Parameter must not be null"); 87 | Executable executable = parameter.getDeclaringExecutable(); 88 | Parameter[] parameters = executable.getParameters(); 89 | for (int i = 0; i < parameters.length; i++) { 90 | if (parameters[i] == parameter) { 91 | return i; 92 | } 93 | } 94 | throw new IllegalStateException(String.format("Failed to resolve index of parameter [%s] in executable [%s]", 95 | parameter, executable.toGenericString())); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/org/springframework/test/context/junit/jupiter/ParameterAutowireUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2016 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.test.context.junit.jupiter; 18 | 19 | import java.lang.annotation.Annotation; 20 | import java.lang.reflect.AnnotatedElement; 21 | import java.lang.reflect.Method; 22 | import java.lang.reflect.Parameter; 23 | import java.util.Optional; 24 | 25 | import org.springframework.beans.BeansException; 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.beans.factory.annotation.Qualifier; 28 | import org.springframework.beans.factory.annotation.Value; 29 | import org.springframework.beans.factory.config.AutowireCapableBeanFactory; 30 | import org.springframework.beans.factory.config.DependencyDescriptor; 31 | import org.springframework.context.ApplicationContext; 32 | import org.springframework.core.MethodParameter; 33 | import org.springframework.core.annotation.AnnotatedElementUtils; 34 | 35 | import static org.springframework.core.annotation.AnnotatedElementUtils.hasAnnotation; 36 | 37 | /** 38 | * Collection of utilities related to autowiring of individual method parameters. 39 | * 40 | * @author Sam Brannen 41 | * @since 5.0 42 | * @see MethodParameterFactory 43 | * @see #isAutowirable(Parameter) 44 | * @see #resolveDependency(Parameter, Class, ApplicationContext) 45 | */ 46 | abstract class ParameterAutowireUtils { 47 | 48 | private ParameterAutowireUtils() { 49 | /* no-op */ 50 | } 51 | 52 | /** 53 | * Determine if the supplied {@link Parameter} can potentially be 54 | * autowired from an {@link ApplicationContext}. 55 | *
Returns {@code true} if the supplied parameter is of type 56 | * {@link ApplicationContext} (or a sub-type thereof) or is annotated or 57 | * meta-annotated with {@link Autowired @Autowired}, 58 | * {@link Qualifier @Qualifier}, or {@link Value @Value}. 59 | * @see #resolveDependency(Parameter, Class, ApplicationContext) 60 | */ 61 | public static boolean isAutowirable(Parameter parameter) { 62 | return ApplicationContext.class.isAssignableFrom(parameter.getType()) 63 | || hasAnnotation(parameter, Autowired.class) 64 | || hasAnnotation(parameter, Qualifier.class) 65 | || hasAnnotation(parameter, Value.class); 66 | } 67 | 68 | /** 69 | * Resolve the dependency for the supplied {@link Parameter} from the 70 | * supplied {@link ApplicationContext}. 71 | *
Provides comprehensive autowiring support for individual method parameters 72 | * on par with Spring's dependency injection facilities for autowired fields and 73 | * methods, including support for {@link Autowired @Autowired}, 74 | * {@link Qualifier @Qualifier}, and {@link Value @Value} with support for property 75 | * placeholders and SpEL expressions in {@code @Value} declarations. 76 | *
The dependency is required unless the parameter is annotated with 77 | * {@link Autowired @Autowired} with the {@link Autowired#required required} 78 | * flag set to {@code false}. 79 | *
If an explicit qualifier is not declared, the name of the parameter
80 | * will be used as the qualifier for resolving ambiguities.
81 | * @param parameter the parameter whose dependency should be resolved
82 | * @param containingClass the concrete class that contains the parameter; this may
83 | * differ from the class that declares the parameter in that it may be a subclass
84 | * thereof, potentially substituting type variables
85 | * @param applicationContext the application context from which to resolve the
86 | * dependency
87 | * @return the resolved object, or {@code null} if none found
88 | * @throws BeansException if dependency resolution failed
89 | * @see #isAutowirable(Parameter)
90 | * @see Autowired#required
91 | * @see MethodParameterFactory#createSynthesizingMethodParameter(Parameter)
92 | * @see AutowireCapableBeanFactory#resolveDependency(DependencyDescriptor, String)
93 | */
94 | public static Object resolveDependency(Parameter parameter, Class> containingClass,
95 | ApplicationContext applicationContext) {
96 |
97 | boolean required = findMergedAnnotation(parameter, Autowired.class).map(Autowired::required).orElse(true);
98 | MethodParameter methodParameter = (parameter.getDeclaringExecutable() instanceof Method
99 | ? MethodParameterFactory.createSynthesizingMethodParameter(parameter)
100 | : MethodParameterFactory.createMethodParameter(parameter));
101 | DependencyDescriptor descriptor = new DependencyDescriptor(methodParameter, required);
102 | descriptor.setContainingClass(containingClass);
103 |
104 | return applicationContext.getAutowireCapableBeanFactory().resolveDependency(descriptor, null);
105 | }
106 |
107 | private static Optional findMergedAnnotation(AnnotatedElement element,
108 | Class annotationType) {
109 |
110 | return Optional.ofNullable(AnnotatedElementUtils.findMergedAnnotation(element, annotationType));
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2017 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter;
18 |
19 | import java.lang.reflect.Constructor;
20 | import java.lang.reflect.Executable;
21 | import java.lang.reflect.Method;
22 | import java.lang.reflect.Parameter;
23 |
24 | import org.junit.jupiter.api.extension.AfterAllCallback;
25 | import org.junit.jupiter.api.extension.AfterEachCallback;
26 | import org.junit.jupiter.api.extension.BeforeAllCallback;
27 | import org.junit.jupiter.api.extension.BeforeEachCallback;
28 | import org.junit.jupiter.api.extension.ExtensionContext;
29 | import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
30 | import org.junit.jupiter.api.extension.ExtensionContext.Store;
31 | import org.junit.jupiter.api.extension.ParameterContext;
32 | import org.junit.jupiter.api.extension.ParameterResolver;
33 | import org.junit.jupiter.api.extension.TestInstancePostProcessor;
34 |
35 | import org.springframework.beans.factory.annotation.Autowired;
36 | import org.springframework.context.ApplicationContext;
37 | import org.springframework.core.annotation.AnnotatedElementUtils;
38 | import org.springframework.test.context.TestContextManager;
39 | import org.springframework.util.Assert;
40 |
41 | /**
42 | * {@code SpringExtension} integrates the Spring TestContext Framework
43 | * into JUnit 5's Jupiter programming model.
44 | *
45 | * To use this extension, simply annotate a JUnit Jupiter based test class with
46 | * {@code @ExtendWith(SpringExtension.class)}, {@code @SpringJUnitJupiterConfig}, or
47 | * {@code @SpringJUnitJupiterWebConfig}.
48 | *
49 | * @author Sam Brannen
50 | * @since 5.0
51 | * @see org.springframework.test.context.junit.jupiter.SpringJUnitJupiterConfig
52 | * @see org.springframework.test.context.junit.jupiter.web.SpringJUnitJupiterWebConfig
53 | * @see org.springframework.test.context.TestContextManager
54 | */
55 | public class SpringExtension implements BeforeAllCallback, AfterAllCallback, TestInstancePostProcessor,
56 | BeforeEachCallback, AfterEachCallback, ParameterResolver {
57 |
58 | /**
59 | * {@link Namespace} in which {@code TestContextManagers} are stored,
60 | * keyed by test class.
61 | */
62 | private static final Namespace NAMESPACE = Namespace.create(SpringExtension.class);
63 |
64 |
65 | /**
66 | * Delegates to {@link TestContextManager#beforeTestClass}.
67 | */
68 | @Override
69 | public void beforeAll(ExtensionContext context) throws Exception {
70 | getTestContextManager(context).beforeTestClass();
71 | }
72 |
73 | /**
74 | * Delegates to {@link TestContextManager#afterTestClass}.
75 | */
76 | @Override
77 | public void afterAll(ExtensionContext context) throws Exception {
78 | try {
79 | getTestContextManager(context).afterTestClass();
80 | }
81 | finally {
82 | getStore(context).remove(context.getRequiredTestClass());
83 | }
84 | }
85 |
86 | /**
87 | * Delegates to {@link TestContextManager#prepareTestInstance}.
88 | */
89 | @Override
90 | public void postProcessTestInstance(Object testInstance, ExtensionContext context) throws Exception {
91 | getTestContextManager(context).prepareTestInstance(testInstance);
92 | }
93 |
94 | /**
95 | * Delegates to {@link TestContextManager#beforeTestMethod}.
96 | */
97 | @Override
98 | public void beforeEach(ExtensionContext context) throws Exception {
99 | Object testInstance = context.getRequiredTestInstance();
100 | Method testMethod = context.getRequiredTestMethod();
101 | getTestContextManager(context).beforeTestMethod(testInstance, testMethod);
102 | }
103 |
104 | /**
105 | * Delegates to {@link TestContextManager#afterTestMethod}.
106 | */
107 | @Override
108 | public void afterEach(ExtensionContext context) throws Exception {
109 | Object testInstance = context.getRequiredTestInstance();
110 | Method testMethod = context.getRequiredTestMethod();
111 | Throwable testException = context.getExecutionException().orElse(null);
112 | getTestContextManager(context).afterTestMethod(testInstance, testMethod, testException);
113 | }
114 |
115 | /**
116 | * Determine if the value for the {@link Parameter} in the supplied {@link ParameterContext}
117 | * should be autowired from the test's {@link ApplicationContext}.
118 | * Returns {@code true} if the parameter is declared in a {@link Constructor}
119 | * that is annotated with {@link Autowired @Autowired} and otherwise delegates to
120 | * {@link ParameterAutowireUtils#isAutowirable}.
121 | * WARNING: If the parameter is declared in a {@code Constructor}
122 | * that is annotated with {@code @Autowired}, Spring will assume the responsibility
123 | * for resolving all parameters in the constructor. Consequently, no other registered
124 | * {@link ParameterResolver} will be able to resolve parameters.
125 | * @see #resolveParameter
126 | * @see ParameterAutowireUtils#isAutowirable
127 | */
128 | @Override
129 | public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
130 | Parameter parameter = parameterContext.getParameter();
131 | Executable executable = parameter.getDeclaringExecutable();
132 | return (executable instanceof Constructor &&
133 | AnnotatedElementUtils.hasAnnotation(executable, Autowired.class)) ||
134 | ParameterAutowireUtils.isAutowirable(parameter);
135 | }
136 |
137 | /**
138 | * Resolve a value for the {@link Parameter} in the supplied {@link ParameterContext} by
139 | * retrieving the corresponding dependency from the test's {@link ApplicationContext}.
140 | * Delegates to {@link ParameterAutowireUtils#resolveDependency}.
141 | * @see #supportsParameter
142 | * @see ParameterAutowireUtils#resolveDependency
143 | */
144 | @Override
145 | public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
146 | Parameter parameter = parameterContext.getParameter();
147 | Class> testClass = extensionContext.getRequiredTestClass();
148 | ApplicationContext applicationContext = getApplicationContext(extensionContext);
149 | return ParameterAutowireUtils.resolveDependency(parameter, testClass, applicationContext);
150 | }
151 |
152 |
153 | /**
154 | * Get the {@link ApplicationContext} associated with the supplied {@code ExtensionContext}.
155 | * @param context the current {@code ExtensionContext} (never {@code null})
156 | * @return the application context
157 | * @throws IllegalStateException if an error occurs while retrieving the application context
158 | * @see org.springframework.test.context.TestContext#getApplicationContext()
159 | */
160 | public static ApplicationContext getApplicationContext(ExtensionContext context) {
161 | return getTestContextManager(context).getTestContext().getApplicationContext();
162 | }
163 |
164 | /**
165 | * Get the {@link TestContextManager} associated with the supplied {@code ExtensionContext}.
166 | * @return the {@code TestContextManager} (never {@code null})
167 | */
168 | private static TestContextManager getTestContextManager(ExtensionContext context) {
169 | Assert.notNull(context, "ExtensionContext must not be null");
170 | Class> testClass = context.getRequiredTestClass();
171 | Store store = getStore(context);
172 | return store.getOrComputeIfAbsent(testClass, TestContextManager::new, TestContextManager.class);
173 | }
174 |
175 | private static Store getStore(ExtensionContext context) {
176 | return context.getRoot().getStore(NAMESPACE);
177 | }
178 |
179 | }
180 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/test/context/junit/jupiter/SpringJUnitJupiterConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter;
18 |
19 | import java.lang.annotation.Documented;
20 | import java.lang.annotation.ElementType;
21 | import java.lang.annotation.Inherited;
22 | import java.lang.annotation.Retention;
23 | import java.lang.annotation.RetentionPolicy;
24 | import java.lang.annotation.Target;
25 |
26 | import org.junit.jupiter.api.extension.ExtendWith;
27 |
28 | import org.springframework.context.ApplicationContextInitializer;
29 | import org.springframework.context.ConfigurableApplicationContext;
30 | import org.springframework.core.annotation.AliasFor;
31 | import org.springframework.test.context.ContextConfiguration;
32 |
33 | /**
34 | * {@code @SpringJUnitJupiterConfig} is a composed annotation that combines
35 | * {@link ExtendWith @ExtendWith(SpringExtension.class)} from JUnit Jupiter with
36 | * {@link ContextConfiguration @ContextConfiguration} from the
37 | * Spring TestContext Framework.
38 | *
39 | * @author Sam Brannen
40 | * @since 5.0
41 | * @see ExtendWith
42 | * @see SpringExtension
43 | * @see ContextConfiguration
44 | * @see org.springframework.test.context.junit.jupiter.web.SpringJUnitJupiterWebConfig
45 | */
46 | @ExtendWith(SpringExtension.class)
47 | @ContextConfiguration
48 | @Documented
49 | @Inherited
50 | @Retention(RetentionPolicy.RUNTIME)
51 | @Target(ElementType.TYPE)
52 | public @interface SpringJUnitJupiterConfig {
53 |
54 | /**
55 | * Alias for {@link ContextConfiguration#classes}.
56 | */
57 | @AliasFor(annotation = ContextConfiguration.class, attribute = "classes")
58 | Class>[] value() default {};
59 |
60 | /**
61 | * Alias for {@link ContextConfiguration#classes}.
62 | */
63 | @AliasFor(annotation = ContextConfiguration.class)
64 | Class>[] classes() default {};
65 |
66 | /**
67 | * Alias for {@link ContextConfiguration#locations}.
68 | */
69 | @AliasFor(annotation = ContextConfiguration.class)
70 | String[] locations() default {};
71 |
72 | /**
73 | * Alias for {@link ContextConfiguration#initializers}.
74 | */
75 | @AliasFor(annotation = ContextConfiguration.class)
76 | Class extends ApplicationContextInitializer extends ConfigurableApplicationContext>>[] initializers() default {};
77 |
78 | /**
79 | * Alias for {@link ContextConfiguration#inheritLocations}.
80 | */
81 | @AliasFor(annotation = ContextConfiguration.class)
82 | boolean inheritLocations() default true;
83 |
84 | /**
85 | * Alias for {@link ContextConfiguration#inheritInitializers}.
86 | */
87 | @AliasFor(annotation = ContextConfiguration.class)
88 | boolean inheritInitializers() default true;
89 |
90 | /**
91 | * Alias for {@link ContextConfiguration#name}.
92 | */
93 | @AliasFor(annotation = ContextConfiguration.class)
94 | String name() default "";
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/test/context/junit/jupiter/web/SpringJUnitJupiterWebConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter.web;
18 |
19 | import java.lang.annotation.Documented;
20 | import java.lang.annotation.ElementType;
21 | import java.lang.annotation.Inherited;
22 | import java.lang.annotation.Retention;
23 | import java.lang.annotation.RetentionPolicy;
24 | import java.lang.annotation.Target;
25 |
26 | import org.junit.jupiter.api.extension.ExtendWith;
27 |
28 | import org.springframework.context.ApplicationContextInitializer;
29 | import org.springframework.context.ConfigurableApplicationContext;
30 | import org.springframework.core.annotation.AliasFor;
31 | import org.springframework.test.context.ContextConfiguration;
32 | import org.springframework.test.context.junit.jupiter.SpringExtension;
33 | import org.springframework.test.context.web.WebAppConfiguration;
34 |
35 | /**
36 | * {@code @SpringJUnitJupiterWebConfig} is a composed annotation that combines
37 | * {@link ExtendWith @ExtendWith(SpringExtension.class)} from JUnit Jupiter with
38 | * {@link ContextConfiguration @ContextConfiguration} and
39 | * {@link WebAppConfiguration @WebAppConfiguration} from the
40 | * Spring TestContext Framework.
41 | *
42 | * @author Sam Brannen
43 | * @since 5.0
44 | * @see ExtendWith
45 | * @see SpringExtension
46 | * @see ContextConfiguration
47 | * @see WebAppConfiguration
48 | * @see org.springframework.test.context.junit.jupiter.SpringJUnitJupiterConfig
49 | */
50 | @ExtendWith(SpringExtension.class)
51 | @ContextConfiguration
52 | @WebAppConfiguration
53 | @Documented
54 | @Inherited
55 | @Retention(RetentionPolicy.RUNTIME)
56 | @Target(ElementType.TYPE)
57 | public @interface SpringJUnitJupiterWebConfig {
58 |
59 | /**
60 | * Alias for {@link ContextConfiguration#classes}.
61 | */
62 | @AliasFor(annotation = ContextConfiguration.class, attribute = "classes")
63 | Class>[] value() default {};
64 |
65 | /**
66 | * Alias for {@link ContextConfiguration#classes}.
67 | */
68 | @AliasFor(annotation = ContextConfiguration.class)
69 | Class>[] classes() default {};
70 |
71 | /**
72 | * Alias for {@link ContextConfiguration#locations}.
73 | */
74 | @AliasFor(annotation = ContextConfiguration.class)
75 | String[] locations() default {};
76 |
77 | /**
78 | * Alias for {@link ContextConfiguration#initializers}.
79 | */
80 | @AliasFor(annotation = ContextConfiguration.class)
81 | Class extends ApplicationContextInitializer extends ConfigurableApplicationContext>>[] initializers() default {};
82 |
83 | /**
84 | * Alias for {@link ContextConfiguration#inheritLocations}.
85 | */
86 | @AliasFor(annotation = ContextConfiguration.class)
87 | boolean inheritLocations() default true;
88 |
89 | /**
90 | * Alias for {@link ContextConfiguration#inheritInitializers}.
91 | */
92 | @AliasFor(annotation = ContextConfiguration.class)
93 | boolean inheritInitializers() default true;
94 |
95 | /**
96 | * Alias for {@link ContextConfiguration#name}.
97 | */
98 | @AliasFor(annotation = ContextConfiguration.class)
99 | String name() default "";
100 |
101 | /**
102 | * Alias for {@link WebAppConfiguration#value}.
103 | */
104 | @AliasFor(annotation = WebAppConfiguration.class, attribute = "value")
105 | String resourcePath() default "src/main/webapp";
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/test/context/junit/jupiter/ComposedSpringExtensionTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter;
18 |
19 | import static org.junit.jupiter.api.Assertions.assertEquals;
20 | import static org.junit.jupiter.api.Assertions.assertNotNull;
21 |
22 | import java.util.List;
23 |
24 | import org.junit.jupiter.api.DisplayName;
25 | import org.junit.jupiter.api.Test;
26 | import org.junit.jupiter.api.extension.ExtendWith;
27 |
28 | import org.springframework.beans.factory.annotation.Autowired;
29 | import org.springframework.context.ApplicationContext;
30 | import org.springframework.test.context.ContextConfiguration;
31 | import org.springframework.test.context.junit.jupiter.comics.Person;
32 |
33 | /**
34 | * Integration tests which demonstrate the composability of annotations
35 | * from JUnit Jupiter and the Spring TestContext Framework.
36 | *
37 | * Note that {@link SpringJUnitJupiterConfig @SpringJUnitJupiterConfig} is
38 | * meta-annotated with JUnit Jupiter's {@link ExtendWith @ExtendWith} and
39 | * Spring's {@link ContextConfiguration @ContextConfiguration}.
40 | *
41 | * To run these tests in an IDE, simply run {@link SpringExtensionTestSuite}
42 | * as a JUnit 4 test.
43 | *
44 | * @author Sam Brannen
45 | * @since 5.0
46 | * @see SpringExtension
47 | * @see SpringJUnitJupiterConfig
48 | * @see SpringExtensionTests
49 | */
50 | @SpringJUnitJupiterConfig(TestConfig.class)
51 | @DisplayName("@SpringJUnitJupiterConfig Tests")
52 | class ComposedSpringExtensionTests {
53 |
54 | @Autowired
55 | Person dilbert;
56 |
57 | @Autowired
58 | List To run these tests in an IDE, simply run {@link SpringExtensionTestSuite}
49 | * as a JUnit 4 test.
50 | *
51 | * @author Sam Brannen
52 | * @since 5.0
53 | * @see SpringExtension
54 | * @see ComposedSpringExtensionTests
55 | */
56 | @ExtendWith(SpringExtension.class)
57 | @ContextConfiguration(classes = TestConfig.class)
58 | @TestPropertySource(properties = "enigma = 42")
59 | class SpringExtensionTests {
60 |
61 | @Autowired
62 | Person dilbert;
63 |
64 | @Autowired
65 | List To run these tests in an IDE, simply run {@link SpringExtensionTestSuite}
36 | * as a JUnit 4 test.
37 | *
38 | * @author Sam Brannen
39 | * @since 5.0
40 | * @see SpringExtension
41 | * @see SpringJUnit5ConstructorInjectionTests
42 | */
43 | @SpringJUnitJupiterConfig(TestConfig.class)
44 | @TestPropertySource(properties = "enigma = 42")
45 | class SpringJUnit5AutowiredConstructorInjectionTests {
46 |
47 | final ApplicationContext applicationContext;
48 | final Person dilbert;
49 | final Dog dog;
50 | final Integer enigma;
51 |
52 | @Autowired
53 | SpringJUnit5AutowiredConstructorInjectionTests(ApplicationContext applicationContext, Person dilbert, Dog dog,
54 | @Value("${enigma}") Integer enigma) {
55 |
56 | this.applicationContext = applicationContext;
57 | this.dilbert = dilbert;
58 | this.dog = dog;
59 | this.enigma = enigma;
60 | }
61 |
62 | @Test
63 | void applicationContextInjected() {
64 | assertNotNull(applicationContext, "ApplicationContext should have been injected by Spring");
65 | assertEquals(this.dilbert, applicationContext.getBean("dilbert", Person.class));
66 | }
67 |
68 | @Test
69 | void beansInjected() {
70 | assertNotNull(this.dilbert, "Dilbert should have been @Autowired by Spring");
71 | assertEquals("Dilbert", this.dilbert.getName(), "Person's name");
72 |
73 | assertNotNull(this.dog, "Dogbert should have been @Autowired by Spring");
74 | assertEquals("Dogbert", this.dog.getName(), "Dog's name");
75 | }
76 |
77 | @Test
78 | void propertyPlaceholderInjected() {
79 | assertNotNull(this.enigma, "Enigma should have been injected via @Value by Spring");
80 | assertEquals(new Integer(42), this.enigma, "enigma");
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/test/context/junit/jupiter/SpringJUnit5ConstructorInjectionTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter;
18 |
19 | import static org.junit.jupiter.api.Assertions.assertEquals;
20 | import static org.junit.jupiter.api.Assertions.assertNotNull;
21 |
22 | import org.junit.jupiter.api.Test;
23 | import org.junit.jupiter.api.TestInfo;
24 |
25 | import org.springframework.beans.factory.annotation.Autowired;
26 | import org.springframework.beans.factory.annotation.Value;
27 | import org.springframework.context.ApplicationContext;
28 | import org.springframework.test.context.TestPropertySource;
29 | import org.springframework.test.context.junit.jupiter.comics.Dog;
30 | import org.springframework.test.context.junit.jupiter.comics.Person;
31 |
32 | /**
33 | * Integration tests which demonstrate support for autowiring individual
34 | * parameters in test class constructors using {@link Autowired @Autowired}
35 | * and {@link Value @Value} with the Spring TestContext Framework and JUnit 5.
36 | *
37 | * To run these tests in an IDE, simply run {@link SpringExtensionTestSuite}
38 | * as a JUnit 4 test.
39 | *
40 | * @author Sam Brannen
41 | * @since 5.0
42 | * @see SpringExtension
43 | * @see SpringJUnit5AutowiredConstructorInjectionTests
44 | */
45 | @SpringJUnitJupiterConfig(TestConfig.class)
46 | @TestPropertySource(properties = "enigma = 42")
47 | class SpringJUnit5ConstructorInjectionTests {
48 |
49 | final ApplicationContext applicationContext;
50 | final Person dilbert;
51 | final Dog dog;
52 | final Integer enigma;
53 | final TestInfo testInfo;
54 |
55 | SpringJUnit5ConstructorInjectionTests(ApplicationContext applicationContext, @Autowired Person dilbert,
56 | @Autowired Dog dog, @Value("${enigma}") Integer enigma, TestInfo testInfo) {
57 |
58 | this.applicationContext = applicationContext;
59 | this.dilbert = dilbert;
60 | this.dog = dog;
61 | this.enigma = enigma;
62 | this.testInfo = testInfo;
63 | }
64 |
65 | @Test
66 | void applicationContextInjected() {
67 | assertNotNull(applicationContext, "ApplicationContext should have been injected by Spring");
68 | assertEquals(this.dilbert, applicationContext.getBean("dilbert", Person.class));
69 | }
70 |
71 | @Test
72 | void beansInjected() {
73 | assertNotNull(this.dilbert, "Dilbert should have been @Autowired by Spring");
74 | assertEquals("Dilbert", this.dilbert.getName(), "Person's name");
75 |
76 | assertNotNull(this.dog, "Dogbert should have been @Autowired by Spring");
77 | assertEquals("Dogbert", this.dog.getName(), "Dog's name");
78 | }
79 |
80 | @Test
81 | void propertyPlaceholderInjected() {
82 | assertNotNull(this.enigma, "Enigma should have been injected via @Value by Spring");
83 | assertEquals(new Integer(42), this.enigma, "enigma");
84 | }
85 |
86 | @Test
87 | void testInfoInjected() {
88 | assertNotNull(this.testInfo, "TestInfo should have been injected by JUnit");
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/test/context/junit/jupiter/TestConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter;
18 |
19 | import org.springframework.context.annotation.Bean;
20 | import org.springframework.context.annotation.Configuration;
21 | import org.springframework.context.annotation.Primary;
22 | import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
23 | import org.springframework.test.context.junit.jupiter.comics.Cat;
24 | import org.springframework.test.context.junit.jupiter.comics.Dog;
25 | import org.springframework.test.context.junit.jupiter.comics.Person;
26 |
27 | /**
28 | * Demo config for tests.
29 | *
30 | * @author Sam Brannen
31 | * @since 5.0
32 | */
33 | @Configuration
34 | public class TestConfig {
35 |
36 | @Bean
37 | static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
38 | return new PropertySourcesPlaceholderConfigurer();
39 | }
40 |
41 | @Bean
42 | Person dilbert() {
43 | return new Person("Dilbert");
44 | }
45 |
46 | @Bean
47 | Person wally() {
48 | return new Person("Wally");
49 | }
50 |
51 | @Bean
52 | Dog dogbert() {
53 | return new Dog("Dogbert");
54 | }
55 |
56 | @Primary
57 | @Bean
58 | Cat catbert() {
59 | return new Cat("Catbert");
60 | }
61 |
62 | @Bean
63 | Cat garfield() {
64 | return new Cat("Garfield");
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/test/context/junit/jupiter/comics/Cat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter.comics;
18 |
19 | /**
20 | * Demo class for tests.
21 | *
22 | * @author Sam Brannen
23 | * @since 5.0
24 | */
25 | public class Cat extends Character {
26 |
27 | public Cat(String name) {
28 | super(name);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/test/context/junit/jupiter/comics/Character.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter.comics;
18 |
19 | /**
20 | * Demo class for tests.
21 | *
22 | * @author Sam Brannen
23 | * @since 5.0
24 | */
25 | public abstract class Character {
26 |
27 | private final String name;
28 |
29 | Character(String name) {
30 | this.name = name;
31 | }
32 |
33 | public String getName() {
34 | return this.name;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/test/context/junit/jupiter/comics/Dog.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter.comics;
18 |
19 | /**
20 | * Demo class for tests.
21 | *
22 | * @author Sam Brannen
23 | * @since 5.0
24 | */
25 | public class Dog extends Character {
26 |
27 | public Dog(String name) {
28 | super(name);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/test/context/junit/jupiter/comics/Person.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter.comics;
18 |
19 | /**
20 | * Demo class for tests.
21 | *
22 | * @author Sam Brannen
23 | * @since 5.0
24 | */
25 | public class Person extends Character {
26 |
27 | public Person(String name) {
28 | super(name);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/test/context/junit/jupiter/defaultmethods/CatInterfaceDefaultMethodsTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter.defaultmethods;
18 |
19 | import org.springframework.test.context.junit.jupiter.SpringExtension;
20 | import org.springframework.test.context.junit.jupiter.comics.Cat;
21 |
22 | /**
23 | * Parameterized test class for integration tests that demonstrate support for
24 | * interface default methods and Java generics in JUnit 5 test classes when used
25 | * with the Spring TestContext Framework and the {@link SpringExtension}.
26 | *
27 | * @author Sam Brannen
28 | * @since 5.0
29 | */
30 | class CatInterfaceDefaultMethodsTests implements GenericComicCharactersInterfaceDefaultMethodsTests To run these tests in an IDE, simply run
41 | * {@link org.springframework.test.context.junit.jupiter.SpringExtensionTestSuite
42 | * SpringExtensionTestSuite} as a JUnit 4 test.
43 | *
44 | * @author Sam Brannen
45 | * @since 5.0
46 | * @see SpringExtension
47 | * @see SpringJUnitJupiterWebConfig
48 | * @see org.springframework.test.context.junit.jupiter.web.WebSpringExtensionTests
49 | */
50 | @SpringJUnitJupiterWebConfig(WebConfig.class)
51 | class MultipleWebRequestsSpringExtensionTests {
52 |
53 | MockMvc mockMvc;
54 |
55 | @BeforeEach
56 | void setUpMockMvc(WebApplicationContext wac) {
57 | this.mockMvc = webAppContextSetup(wac)
58 | .alwaysExpect(status().isOk())
59 | .alwaysExpect(content().contentTypeCompatibleWith(APPLICATION_JSON))
60 | .build();
61 | }
62 |
63 | @Test
64 | void getPerson42() throws Exception {
65 | this.mockMvc.perform(get("/person/42"))
66 | .andExpect(jsonPath("$.name", is("Dilbert")));
67 | }
68 |
69 | @Test
70 | void getPerson99() throws Exception {
71 | this.mockMvc.perform(get("/person/99"))
72 | .andExpect(jsonPath("$.name", is("Wally")));
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/test/context/junit/jupiter/web/PersonController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter.web;
18 |
19 | import org.springframework.test.context.junit.jupiter.comics.Person;
20 | import org.springframework.web.bind.annotation.GetMapping;
21 | import org.springframework.web.bind.annotation.PathVariable;
22 | import org.springframework.web.bind.annotation.RestController;
23 |
24 | /**
25 | * @author Sam Brannen
26 | * @since 5.0
27 | */
28 | @RestController
29 | class PersonController {
30 |
31 | @GetMapping("/person/{id}")
32 | Person getPerson(@PathVariable long id) {
33 | if (id == 42) {
34 | return new Person("Dilbert");
35 | }
36 | return new Person("Wally");
37 | }
38 |
39 | }
--------------------------------------------------------------------------------
/src/test/java/org/springframework/test/context/junit/jupiter/web/WebConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter.web;
18 |
19 | import org.springframework.context.annotation.Bean;
20 | import org.springframework.context.annotation.Configuration;
21 | import org.springframework.web.servlet.config.annotation.EnableWebMvc;
22 |
23 | /**
24 | * @author Sam Brannen
25 | * @since 5.0
26 | */
27 | @Configuration
28 | @EnableWebMvc
29 | class WebConfig {
30 |
31 | @Bean
32 | PersonController personController() {
33 | return new PersonController();
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/src/test/java/org/springframework/test/context/junit/jupiter/web/WebSpringExtensionTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter.web;
18 |
19 | import static org.hamcrest.CoreMatchers.is;
20 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
21 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
22 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
23 | import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
24 |
25 | import org.junit.jupiter.api.DisplayName;
26 | import org.junit.jupiter.api.Test;
27 |
28 | import org.springframework.test.context.junit.jupiter.SpringExtension;
29 | import org.springframework.test.web.servlet.MockMvc;
30 | import org.springframework.web.context.WebApplicationContext;
31 |
32 | /**
33 | * Integration tests which demonstrate use of the Spring MVC Test Framework
34 | * and the Spring TestContext Framework with current JUnit 5 snapshots
35 | * and the {@link SpringExtension} (via a custom
36 | * {@link SpringJUnitJupiterWebConfig @SpringJUnitJupiterWebConfig} composed annotation).
37 | *
38 | * Note how the {@link #springMvcTest(WebApplicationContext)} test method
39 | * has the {@link WebApplicationContext} injected as a method parameter.
40 | * This allows the {@link MockMvc} instance to be configured local to the
41 | * test method without any fields in the test class.
42 | *
43 | * To run these tests in an IDE, simply run
44 | * {@link org.springframework.test.context.junit.jupiter.SpringExtensionTestSuite
45 | * SpringExtensionTestSuite} as a JUnit 4 test.
46 | *
47 | * @author Sam Brannen
48 | * @since 5.0
49 | * @see SpringExtension
50 | * @see SpringJUnitJupiterWebConfig
51 | * @see org.springframework.test.context.junit.jupiter.web.MultipleWebRequestsSpringExtensionTests
52 | * @see org.springframework.test.context.junit.jupiter.SpringExtensionTests
53 | * @see org.springframework.test.context.junit.jupiter.ComposedSpringExtensionTests
54 | */
55 | @SpringJUnitJupiterWebConfig(WebConfig.class)
56 | @DisplayName("Web SpringExtension Tests")
57 | class WebSpringExtensionTests {
58 |
59 | @Test
60 | void springMvcTest(WebApplicationContext wac) throws Exception {
61 | webAppContextSetup(wac).build()
62 | .perform(get("/person/42"))
63 | .andExpect(status().isOk())
64 | .andExpect(jsonPath("$.name", is("Dilbert")));
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/test/context/junit/jupiter/xml/XmlSpringExtensionTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2002-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.test.context.junit.jupiter.xml;
18 |
19 | import static org.junit.jupiter.api.Assertions.assertEquals;
20 | import static org.junit.jupiter.api.Assertions.assertNotNull;
21 |
22 | import java.util.List;
23 |
24 | import org.junit.jupiter.api.Test;
25 | import org.junit.jupiter.api.extension.ExtendWith;
26 |
27 | import org.springframework.beans.factory.annotation.Autowired;
28 | import org.springframework.beans.factory.annotation.Qualifier;
29 | import org.springframework.context.ApplicationContext;
30 | import org.springframework.context.support.GenericApplicationContext;
31 | import org.springframework.test.context.ContextConfiguration;
32 | import org.springframework.test.context.junit.jupiter.SpringExtension;
33 | import org.springframework.test.context.junit.jupiter.SpringExtensionTestSuite;
34 | import org.springframework.test.context.junit.jupiter.comics.Person;
35 |
36 | /**
37 | * Integration tests which demonstrate that the Spring TestContext Framework can
38 | * be used with the current JUnit 5 snapshots via a single {@link SpringExtension}
39 | * in conjunction with XML Spring configuration files.
40 | *
41 | * To run these tests in an IDE, simply run {@link SpringExtensionTestSuite}
42 | * as a JUnit 4 test.
43 | *
44 | * @author Sam Brannen
45 | * @since 5.0
46 | * @see SpringExtension
47 | */
48 | @ExtendWith(SpringExtension.class)
49 | @ContextConfiguration("classpath:test-config.xml")
50 | class XmlSpringExtensionTests {
51 |
52 | @Autowired
53 | Person dilbert;
54 |
55 | @Autowired
56 | List