Merge branch '6.2.x'

This commit is contained in:
Sam Brannen
2025-10-22 17:09:38 +02:00
22 changed files with 1865 additions and 48 deletions
@@ -19,6 +19,7 @@ package org.springframework.test.context.bean.override.convention;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
@@ -30,14 +31,15 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link TestBean} that use by-name lookup.
* Integration tests for {@link TestBean} that use by-name lookup with test class
* {@link ExtensionContextScope}.
*
* @author Simon Baslé
* @author Sam Brannen
* @since 6.2
*/
@SpringJUnitConfig
public class TestBeanByNameLookupIntegrationTests {
public class TestBeanByNameLookupTestClassScopedExtensionContextIntegrationTests {
@TestBean(name = "field")
String field;
@@ -0,0 +1,205 @@
/*
* Copyright 2002-present 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
*
* https://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.bean.override.convention;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
/**
* Integration tests for {@link TestBean} that use by-name lookup with
* {@link ExtensionContextScope#TEST_METHOD}.
*
* @author Simon Baslé
* @author Sam Brannen
* @since 6.2.13
*/
public class TestBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests {
@Test
void runTests() {
EngineTestKit.engine("junit-jupiter")
.configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
.selectors(selectClass(TestCase.class))
.execute()
.testEvents()
.assertStatistics(stats -> stats.started(12).succeeded(12).failed(0));
}
@SpringJUnitConfig
public static class TestCase {
@TestBean(name = "field")
String field;
@TestBean(name = "methodRenamed1", methodName = "field")
String methodRenamed1;
static String field() {
return "fieldOverride";
}
static String nestedField() {
return "nestedFieldOverride";
}
@Test
void fieldHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("field")).as("applicationContext").isEqualTo("fieldOverride");
assertThat(field).as("injection point").isEqualTo("fieldOverride");
}
@Test
void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("methodRenamed1")).as("applicationContext").isEqualTo("fieldOverride");
assertThat(methodRenamed1).as("injection point").isEqualTo("fieldOverride");
}
@Nested
@DisplayName("With @TestBean in enclosing class and in @Nested class")
public class TestBeanFieldInEnclosingClassTestCase {
@TestBean(name = "nestedField")
String nestedField;
@TestBean(name = "methodRenamed2", methodName = "nestedField")
String methodRenamed2;
@Test
void fieldHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("field")).as("applicationContext").isEqualTo("fieldOverride");
assertThat(field).as("injection point").isEqualTo("fieldOverride");
}
@Test
void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("methodRenamed1")).as("applicationContext").isEqualTo("fieldOverride");
assertThat(methodRenamed1).as("injection point").isEqualTo("fieldOverride");
}
@Test
void nestedFieldHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
assertThat(nestedField).isEqualTo("nestedFieldOverride");
}
@Test
void nestedFieldWithMethodNameHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("methodRenamed2")).as("applicationContext").isEqualTo("nestedFieldOverride");
assertThat(methodRenamed2).isEqualTo("nestedFieldOverride");
}
@Nested
@DisplayName("With @TestBean in the enclosing classes")
public class TestBeanFieldInEnclosingClassLevel2TestCase {
@Test
void fieldHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("field")).as("applicationContext").isEqualTo("fieldOverride");
assertThat(field).as("injection point").isEqualTo("fieldOverride");
}
@Test
void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("methodRenamed1")).as("applicationContext").isEqualTo("fieldOverride");
assertThat(methodRenamed1).as("injection point").isEqualTo("fieldOverride");
}
@Test
void nestedFieldHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
assertThat(nestedField).isEqualTo("nestedFieldOverride");
}
@Test
void nestedFieldWithMethodNameHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("methodRenamed2")).as("applicationContext").isEqualTo("nestedFieldOverride");
assertThat(methodRenamed2).isEqualTo("nestedFieldOverride");
}
}
}
@Nested
@DisplayName("With factory method in enclosing class")
public class TestBeanFactoryMethodInEnclosingClassTestCase {
@TestBean(methodName = "nestedField", name = "nestedField")
String nestedField;
@Test
void nestedFieldHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
assertThat(nestedField).isEqualTo("nestedFieldOverride");
}
@Nested
@DisplayName("With factory method in the enclosing class of the enclosing class")
public class TestBeanFactoryMethodInEnclosingClassLevel2TestCase {
@TestBean(methodName = "nestedField", name = "nestedNestedField")
String nestedNestedField;
@Test
void nestedFieldHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("nestedNestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
assertThat(nestedNestedField).isEqualTo("nestedFieldOverride");
}
}
}
}
@Configuration(proxyBeanMethods = false)
static class Config {
@Bean("field")
String bean1() {
return "prod";
}
@Bean("nestedField")
String bean2() {
return "nestedProd";
}
@Bean("methodRenamed1")
String bean3() {
return "Prod";
}
@Bean("methodRenamed2")
String bean4() {
return "NestedProd";
}
}
}
@@ -19,6 +19,7 @@ package org.springframework.test.context.bean.override.mockito;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -35,14 +36,15 @@ import org.springframework.test.mockito.MockitoAssertions;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link MockitoBean} that use by-name lookup.
* Integration tests for {@link MockitoBean} that use by-name lookup with test class
* {@link ExtensionContextScope}.
*
* @author Simon Baslé
* @author Sam Brannen
* @since 6.2
*/
@SpringJUnitConfig
public class MockitoBeanByNameLookupIntegrationTests {
public class MockitoBeanByNameLookupTestClassScopedExtensionContextIntegrationTests {
@MockitoBean("field")
ExampleService field;
@@ -0,0 +1,164 @@
/*
* Copyright 2002-present 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
*
* https://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.bean.override.mockito;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.bean.override.example.ExampleService;
import org.springframework.test.context.bean.override.example.RealExampleService;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.mockito.MockitoAssertions;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
/**
* Integration tests for {@link MockitoBean} that use by-name lookup with
* {@link ExtensionContextScope#TEST_METHOD}.
*
* @author Simon Baslé
* @author Sam Brannen
* @since 6.2.13
*/
public class MockitoBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests {
@Test
void runTests() {
EngineTestKit.engine("junit-jupiter")
.configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
.selectors(selectClass(TestCase.class))
.execute()
.testEvents()
.assertStatistics(stats -> stats.started(6).succeeded(6).failed(0));
}
@SpringJUnitConfig
public static class TestCase {
@MockitoBean("field")
ExampleService field;
@MockitoBean("nonExistingBean")
ExampleService nonExisting;
@Test
void fieldAndRenamedFieldHaveSameOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("field"))
.isInstanceOf(ExampleService.class)
.satisfies(MockitoAssertions::assertIsMock)
.isSameAs(field);
assertThat(field.greeting()).as("mocked greeting").isNull();
}
@Test
void fieldIsMockedWhenNoOriginalBean(ApplicationContext ctx) {
assertThat(ctx.getBean("nonExistingBean"))
.isInstanceOf(ExampleService.class)
.satisfies(MockitoAssertions::assertIsMock)
.isSameAs(nonExisting);
assertThat(nonExisting.greeting()).as("mocked greeting").isNull();
}
@Nested
@DisplayName("With @MockitoBean in enclosing class and in @Nested class")
public class MockitoBeanNestedTestCase {
@Autowired
@Qualifier("field")
ExampleService localField;
@Autowired
@Qualifier("nonExistingBean")
ExampleService localNonExisting;
@MockitoBean("nestedField")
ExampleService nestedField;
@MockitoBean("nestedNonExistingBean")
ExampleService nestedNonExisting;
@Test
void fieldAndRenamedFieldHaveSameOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("field"))
.isInstanceOf(ExampleService.class)
.satisfies(MockitoAssertions::assertIsMock)
.isSameAs(localField);
assertThat(localField.greeting()).as("mocked greeting").isNull();
}
@Test
void fieldIsMockedWhenNoOriginalBean(ApplicationContext ctx) {
assertThat(ctx.getBean("nonExistingBean"))
.isInstanceOf(ExampleService.class)
.satisfies(MockitoAssertions::assertIsMock)
.isSameAs(localNonExisting);
assertThat(localNonExisting.greeting()).as("mocked greeting").isNull();
}
@Test
void nestedFieldAndRenamedFieldHaveSameOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("nestedField"))
.isInstanceOf(ExampleService.class)
.satisfies(MockitoAssertions::assertIsMock)
.isSameAs(nestedField);
}
@Test
void nestedFieldIsMockedWhenNoOriginalBean(ApplicationContext ctx) {
assertThat(ctx.getBean("nestedNonExistingBean"))
.isInstanceOf(ExampleService.class)
.satisfies(MockitoAssertions::assertIsMock)
.isSameAs(nestedNonExisting);
}
}
}
@Configuration(proxyBeanMethods = false)
static class Config {
@Bean("field")
ExampleService bean1() {
return new RealExampleService("Hello Field");
}
@Bean("nestedField")
ExampleService bean2() {
return new RealExampleService("Hello Nested Field");
}
}
}
@@ -19,6 +19,7 @@ package org.springframework.test.context.bean.override.mockito;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -29,21 +30,22 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.test.context.bean.override.example.ExampleService;
import org.springframework.test.context.bean.override.example.RealExampleService;
import org.springframework.test.context.bean.override.mockito.MockitoSpyBeanByNameLookupIntegrationTests.Config;
import org.springframework.test.context.bean.override.mockito.MockitoSpyBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.Config;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.mockito.MockitoAssertions;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link MockitoSpyBean} that use by-name lookup.
* Integration tests for {@link MockitoSpyBean} that use by-name lookup with test class
* {@link ExtensionContextScope}.
*
* @author Simon Baslé
* @author Sam Brannen
* @since 6.2
*/
@SpringJUnitConfig(Config.class)
public class MockitoSpyBeanByNameLookupIntegrationTests {
public class MockitoSpyBeanByNameLookupTestClassScopedExtensionContextIntegrationTests {
@MockitoSpyBean("field1")
ExampleService field;
@@ -0,0 +1,126 @@
/*
* Copyright 2002-present 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
*
* https://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.bean.override.mockito;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.bean.override.example.ExampleService;
import org.springframework.test.context.bean.override.example.RealExampleService;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.mockito.MockitoAssertions;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
/**
* Integration tests for {@link MockitoSpyBean} that use by-name lookup with
* {@link ExtensionContextScope#TEST_METHOD}.
*
* @author Simon Baslé
* @author Sam Brannen
* @since 6.2.13
*/
public class MockitoSpyBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests {
@Test
void runTests() {
EngineTestKit.engine("junit-jupiter")
.configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
.selectors(selectClass(TestCase.class))
.execute()
.testEvents()
.assertStatistics(stats -> stats.started(3).succeeded(3).failed(0));
}
@SpringJUnitConfig(Config.class)
public static class TestCase {
@MockitoSpyBean("field1")
ExampleService field;
@Test
void fieldHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("field1"))
.isInstanceOf(ExampleService.class)
.satisfies(MockitoAssertions::assertIsSpy)
.isSameAs(field);
assertThat(field.greeting()).isEqualTo("bean1");
}
@Nested
@DisplayName("With @MockitoSpyBean in enclosing class and in @Nested class")
public class MockitoSpyBeanNestedTestCase {
@Autowired
@Qualifier("field1")
ExampleService localField;
@MockitoSpyBean("field2")
ExampleService nestedField;
@Test
void fieldHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("field1"))
.isInstanceOf(ExampleService.class)
.satisfies(MockitoAssertions::assertIsSpy)
.isSameAs(localField);
assertThat(localField.greeting()).isEqualTo("bean1");
}
@Test
void nestedFieldHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("field2"))
.isInstanceOf(ExampleService.class)
.satisfies(MockitoAssertions::assertIsSpy)
.isSameAs(nestedField);
assertThat(nestedField.greeting()).isEqualTo("bean2");
}
}
}
@Configuration(proxyBeanMethods = false)
static class Config {
@Bean("field1")
ExampleService bean1() {
return new RealExampleService("bean1");
}
@Bean("field2")
ExampleService bean2() {
return new RealExampleService("bean2");
}
}
}
@@ -20,6 +20,7 @@ import java.util.List;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -30,7 +31,7 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.context.junit.jupiter.nested.ActiveProfilesNestedTests.Config1;
import org.springframework.test.context.junit.jupiter.nested.ActiveProfilesTestClassScopedExtensionContextNestedTests.Config1;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
@@ -39,7 +40,8 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
/**
* Integration tests that verify support for {@code @Nested} test classes using
* {@link ActiveProfiles @ActiveProfiles} in conjunction with the
* {@link SpringExtension} in a JUnit Jupiter environment.
* {@link SpringExtension} in a JUnit Jupiter environment with test class
* {@link ExtensionContextScope}.
*
* @author Sam Brannen
* @since 5.3
@@ -47,7 +49,7 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
@SpringJUnitConfig(Config1.class)
@ActiveProfiles("1")
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class ActiveProfilesNestedTests {
class ActiveProfilesTestClassScopedExtensionContextNestedTests {
@Autowired
List<String> strings;
@@ -69,8 +71,9 @@ class ActiveProfilesNestedTests {
@Test
void test() {
assertThat(strings).containsExactlyInAnyOrder("X", "A1");
assertThat(this.localStrings).containsExactlyInAnyOrder("X", "A1");
assertThat(strings)
.isEqualTo(this.localStrings)
.containsExactlyInAnyOrder("X", "A1");
}
}
@@ -0,0 +1,236 @@
/*
* Copyright 2002-present 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
*
* https://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.nested;
import java.util.List;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
/**
* Integration tests that verify support for {@code @Nested} test classes using
* {@link ActiveProfiles @ActiveProfiles} in conjunction with the
* {@link SpringExtension} in a JUnit Jupiter environment with
* {@link ExtensionContextScope#TEST_METHOD}.
*
* @author Sam Brannen
* @since 6.2.13
*/
class ActiveProfilesTestMethodScopedExtensionContextNestedTests {
@Test
void runTests() {
EngineTestKit.engine("junit-jupiter")
.configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
.selectors(selectClass(TestCase.class))
.execute()
.testEvents()
.assertStatistics(stats -> stats.started(7).succeeded(7).failed(0));
}
@SpringJUnitConfig(Config1.class)
@ActiveProfiles("1")
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
static class TestCase {
@Autowired
List<String> strings;
@Test
void test() {
assertThat(this.strings).containsExactlyInAnyOrder("X", "A1");
}
@Nested
@NestedTestConfiguration(INHERIT)
class InheritedConfigTestCase {
@Autowired
List<String> localStrings;
@Test
void test() {
assertThat(strings)
.isEqualTo(this.localStrings)
.containsExactlyInAnyOrder("X", "A1");
}
}
@Nested
@SpringJUnitConfig(Config2.class)
@ActiveProfiles("2")
class ConfigOverriddenByDefaultTestCase {
@Autowired
List<String> localStrings;
@Test
void test() {
assertThat(strings)
.isEqualTo(this.localStrings)
.containsExactlyInAnyOrder("Y", "A2");
}
}
@Nested
@NestedTestConfiguration(INHERIT)
@ContextConfiguration(classes = Config2.class)
@ActiveProfiles("2")
class InheritedAndExtendedConfigTestCase {
@Autowired
List<String> localStrings;
@Test
void test() {
assertThat(strings)
.isEqualTo(this.localStrings)
.containsExactlyInAnyOrder("X", "A1", "Y", "A2");
}
@Nested
@NestedTestConfiguration(OVERRIDE)
@SpringJUnitConfig({ Config1.class, Config2.class, Config3.class })
@ActiveProfiles("3")
class DoubleNestedWithOverriddenConfigTestCase {
@Autowired
List<String> localStrings;
@Test
void test() {
assertThat(strings)
.isEqualTo(this.localStrings)
.containsExactlyInAnyOrder("X", "Y", "Z", "A3");
}
@Nested
@NestedTestConfiguration(INHERIT)
@ActiveProfiles(profiles = "2", inheritProfiles = false)
class TripleNestedWithInheritedConfigButOverriddenProfilesTestCase {
@Autowired
List<String> localStrings;
@Test
void test() {
assertThat(strings)
.isEqualTo(this.localStrings)
.containsExactlyInAnyOrder("X", "Y", "Z", "A2");
}
}
@Nested
@NestedTestConfiguration(INHERIT)
class TripleNestedWithInheritedConfigAndTestInterfaceTestCase implements TestInterface {
@Autowired
List<String> localStrings;
@Test
void test() {
assertThat(strings)
.isEqualTo(this.localStrings)
.containsExactlyInAnyOrder("X", "Y", "Z", "A2", "A3");
}
}
}
}
}
// -------------------------------------------------------------------------
@Configuration
static class Config1 {
@Bean
String x() {
return "X";
}
@Bean
@Profile("1")
String a1() {
return "A1";
}
}
@Configuration
static class Config2 {
@Bean
String y() {
return "Y";
}
@Bean
@Profile("2")
String a2() {
return "A2";
}
}
@Configuration
static class Config3 {
@Bean
String z() {
return "Z";
}
@Bean
@Profile("3")
String a3() {
return "A3";
}
}
@ActiveProfiles("2")
interface TestInterface {
}
}
@@ -19,6 +19,7 @@ package org.springframework.test.context.junit.jupiter.nested;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -28,28 +29,29 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.context.junit.jupiter.nested.ConstructorInjectionNestedTests.TopLevelConfig;
import org.springframework.test.context.junit.jupiter.nested.ConstructorInjectionTestClassScopedExtensionContextNestedTests.TopLevelConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
/**
* Integration tests that verify support for {@code @Nested} test classes in conjunction
* with the {@link SpringExtension} in a JUnit Jupiter environment ... when using
* constructor injection as opposed to field injection (see SPR-16653).
* with the {@link SpringExtension} in a JUnit Jupiter environment with test class
* {@link ExtensionContextScope} ... when using constructor injection as opposed
* to field injection (see SPR-16653).
*
* @author Sam Brannen
* @since 5.0.5
* @see ContextConfigurationNestedTests
* @see ContextConfigurationTestClassScopedExtensionContextNestedTests
* @see org.springframework.test.context.junit4.nested.NestedTestsWithSpringRulesTests
*/
@SpringJUnitConfig(TopLevelConfig.class)
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class ConstructorInjectionNestedTests {
class ConstructorInjectionTestClassScopedExtensionContextNestedTests {
final String foo;
ConstructorInjectionNestedTests(TestInfo testInfo, @Autowired String foo) {
ConstructorInjectionTestClassScopedExtensionContextNestedTests(TestInfo testInfo, @Autowired String foo) {
this.foo = foo;
}
@@ -0,0 +1,173 @@
/*
* Copyright 2002-present 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
*
* https://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.nested;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.junit.platform.testkit.engine.EngineTestKit;
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.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
/**
* Integration tests that verify support for {@code @Nested} test classes in conjunction
* with the {@link SpringExtension} in a JUnit Jupiter environment with
* {@link ExtensionContextScope#TEST_METHOD} ... when using constructor injection
* as opposed to field injection (see SPR-16653).
*
* @author Sam Brannen
* @since 6.2.13
* @see ContextConfigurationTestClassScopedExtensionContextNestedTests
* @see org.springframework.test.context.junit4.nested.NestedTestsWithSpringRulesTests
*/
class ConstructorInjectionTestMethodScopedExtensionContextNestedTests {
@Test
void runTests() {
EngineTestKit.engine("junit-jupiter")
.configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
.selectors(selectClass(TestCase.class))
.execute()
.testEvents()
.assertStatistics(stats -> stats.started(5).succeeded(5).failed(0));
}
@SpringJUnitConfig(TopLevelConfig.class)
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
static class TestCase {
final String foo;
TestCase(TestInfo testInfo, @Autowired String foo) {
this.foo = foo;
}
@Test
void topLevelTest() {
assertThat(foo).isEqualTo("foo");
}
@Nested
@SpringJUnitConfig(NestedConfig.class)
class AutowiredConstructorTestCase {
final String bar;
@Autowired
AutowiredConstructorTestCase(String bar) {
this.bar = bar;
}
@Test
void nestedTest() {
assertThat(foo).isEqualTo("bar");
assertThat(bar).isEqualTo("bar");
}
}
@Nested
@SpringJUnitConfig(NestedConfig.class)
class AutowiredConstructorParameterTestCase {
final String bar;
AutowiredConstructorParameterTestCase(@Autowired String bar) {
this.bar = bar;
}
@Test
void nestedTest() {
assertThat(foo).isEqualTo("bar");
assertThat(bar).isEqualTo("bar");
}
}
@Nested
@SpringJUnitConfig(NestedConfig.class)
class QualifiedConstructorParameterTestCase {
final String bar;
QualifiedConstructorParameterTestCase(TestInfo testInfo, @Qualifier("bar") String s) {
this.bar = s;
}
@Test
void nestedTest() {
assertThat(foo).isEqualTo("bar");
assertThat(bar).isEqualTo("bar");
}
}
@Nested
@SpringJUnitConfig(NestedConfig.class)
class SpelConstructorParameterTestCase {
final String bar;
final int answer;
SpelConstructorParameterTestCase(@Autowired String bar, TestInfo testInfo, @Value("#{ 6 * 7 }") int answer) {
this.bar = bar;
this.answer = answer;
}
@Test
void nestedTest() {
assertThat(foo).isEqualTo("bar");
assertThat(bar).isEqualTo("bar");
assertThat(answer).isEqualTo(42);
}
}
}
// -------------------------------------------------------------------------
@Configuration
static class TopLevelConfig {
@Bean
String foo() {
return "foo";
}
}
@Configuration
static class NestedConfig {
@Bean
String bar() {
return "bar";
}
}
}
@@ -18,6 +18,7 @@ package org.springframework.test.context.junit.jupiter.nested;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -27,7 +28,7 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.context.junit.jupiter.nested.ContextConfigurationNestedTests.TopLevelConfig;
import org.springframework.test.context.junit.jupiter.nested.ContextConfigurationTestClassScopedExtensionContextNestedTests.TopLevelConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
@@ -36,16 +37,17 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
/**
* Integration tests that verify support for {@code @Nested} test classes using
* {@link ContextConfiguration @ContextConfiguration} in conjunction with the
* {@link SpringExtension} in a JUnit Jupiter environment.
* {@link SpringExtension} in a JUnit Jupiter environment with test class
* {@link ExtensionContextScope}.
*
* @author Sam Brannen
* @since 5.0
* @see ConstructorInjectionNestedTests
* @see ConstructorInjectionTestClassScopedExtensionContextNestedTests
* @see org.springframework.test.context.junit4.nested.NestedTestsWithSpringRulesTests
*/
@SpringJUnitConfig(TopLevelConfig.class)
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class ContextConfigurationNestedTests {
class ContextConfigurationTestClassScopedExtensionContextNestedTests {
private static final String FOO = "foo";
private static final String BAR = "bar";
@@ -0,0 +1,234 @@
/*
* Copyright 2002-present 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
*
* https://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.nested;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
/**
* Integration tests that verify support for {@code @Nested} test classes using
* {@link ContextConfiguration @ContextConfiguration} in conjunction with the
* {@link SpringExtension} in a JUnit Jupiter environment with
* {@link ExtensionContextScope#TEST_METHOD}.
*
* @author Sam Brannen
* @since 6.2.13
* @see ConstructorInjectionTestClassScopedExtensionContextNestedTests
* @see org.springframework.test.context.junit4.nested.NestedTestsWithSpringRulesTests
*/
class ContextConfigurationTestMethodScopedExtensionContextNestedTests {
private static final String FOO = "foo";
private static final String BAR = "bar";
private static final String BAZ = "baz";
@Test
void runTests() {
EngineTestKit.engine("junit-jupiter")
.configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
.selectors(selectClass(TestCase.class))
.execute()
.testEvents()
.assertStatistics(stats -> stats.started(6).succeeded(6).failed(0));
}
@SpringJUnitConfig(TopLevelConfig.class)
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
static class TestCase {
private static final String FOO = "foo";
private static final String BAR = "bar";
private static final String BAZ = "baz";
@Autowired(required = false)
@Qualifier("foo")
String foo;
@Test
void topLevelTest() {
assertThat(foo).isEqualTo(FOO);
}
@Nested
@SpringJUnitConfig(NestedConfig.class)
class NestedTestCase {
@Autowired(required = false)
@Qualifier("foo")
String localFoo;
@Autowired
String bar;
@Test
void test() {
assertThat(foo).as("foo bean should not be present").isNull();
assertThat(this.localFoo).as("local foo bean should not be present").isNull();
assertThat(this.bar).isEqualTo(BAR);
}
}
@Nested
@NestedTestConfiguration(INHERIT)
class NestedTestCaseWithInheritedConfigTestCase {
@Autowired(required = false)
@Qualifier("foo")
String localFoo;
@Autowired
String bar;
@Test
void test() {
// Since the configuration is inherited, the foo field in the outer instance
// and the bar field in the inner instance should both have been injected
// from the test ApplicationContext for the outer instance.
assertThat(foo).isEqualTo(FOO);
assertThat(this.localFoo).isEqualTo(FOO);
assertThat(this.bar).isEqualTo(FOO);
}
@Nested
@NestedTestConfiguration(OVERRIDE)
@SpringJUnitConfig(NestedConfig.class)
class DoubleNestedWithOverriddenConfigTestCase {
@Autowired(required = false)
@Qualifier("foo")
String localFoo;
@Autowired
String bar;
@Test
void test() {
assertThat(foo).as("foo bean should not be present").isNull();
assertThat(this.localFoo).as("local foo bean should not be present").isNull();
assertThat(this.bar).isEqualTo(BAR);
}
@Nested
@NestedTestConfiguration(INHERIT)
class TripleNestedWithInheritedConfigTestCase {
@Autowired(required = false)
@Qualifier("foo")
String localFoo;
@Autowired
String bar;
@Test
void test() {
assertThat(foo).as("foo bean should not be present").isNull();
assertThat(this.localFoo).as("local foo bean should not be present").isNull();
assertThat(this.bar).isEqualTo(BAR);
}
}
@Nested
@NestedTestConfiguration(INHERIT)
class TripleNestedWithInheritedConfigAndTestInterfaceTestCase implements TestInterface {
@Autowired(required = false)
@Qualifier("foo")
String localFoo;
@Autowired
@Qualifier("bar")
String bar;
@Autowired
String baz;
@Test
void test() {
assertThat(foo).as("foo bean should not be present").isNull();
assertThat(this.localFoo).as("local foo bean should not be present").isNull();
assertThat(this.bar).isEqualTo(BAR);
assertThat(this.baz).isEqualTo(BAZ);
}
}
}
}
}
// -------------------------------------------------------------------------
@Configuration
static class TopLevelConfig {
@Bean
String foo() {
return FOO;
}
}
@Configuration
static class NestedConfig {
@Bean
String bar() {
return BAR;
}
}
@Configuration
static class TestInterfaceConfig {
@Bean
String baz() {
return BAZ;
}
}
@ContextConfiguration(classes = TestInterfaceConfig.class)
interface TestInterface {
}
}
@@ -19,6 +19,7 @@ package org.springframework.test.context.junit.jupiter.nested;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -30,7 +31,7 @@ import org.springframework.test.context.ContextHierarchy;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.aot.DisabledInAotMode;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.nested.ContextHierarchyNestedTests.ParentConfig;
import org.springframework.test.context.junit.jupiter.nested.ContextHierarchyTestClassScopedExtensionContextNestedTests.ParentConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
@@ -39,7 +40,8 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
/**
* Integration tests that verify support for {@code @Nested} test classes using
* {@link ContextHierarchy @ContextHierarchy} in conjunction with the
* {@link SpringExtension} in a JUnit Jupiter environment.
* {@link SpringExtension} in a JUnit Jupiter environment with test class
* {@link ExtensionContextScope}.
*
* @author Sam Brannen
* @since 5.3
@@ -48,7 +50,7 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
@ContextHierarchy(@ContextConfiguration(classes = ParentConfig.class))
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
@DisabledInAotMode("@ContextHierarchy is not supported in AOT")
class ContextHierarchyNestedTests {
class ContextHierarchyTestClassScopedExtensionContextNestedTests {
private static final String FOO = "foo";
private static final String BAR = "bar";
@@ -97,7 +99,7 @@ class ContextHierarchyNestedTests {
@Nested
@NestedTestConfiguration(INHERIT)
@ContextConfiguration(classes = Child1Config.class)
class NestedTestCaseWithInheritedConfigTests {
class NestedInheritedCfgTests {
@Autowired
String bar;
@@ -125,7 +127,7 @@ class ContextHierarchyNestedTests {
@ContextConfiguration(classes = ParentConfig.class),
@ContextConfiguration(classes = Child2Config.class)
})
class DoubleNestedTestCaseWithOverriddenConfigTests {
class DoubleNestedOverriddenCfgTests {
@Autowired
String bar;
@@ -146,7 +148,7 @@ class ContextHierarchyNestedTests {
@Nested
@NestedTestConfiguration(INHERIT)
class TripleNestedWithInheritedConfigAndTestInterfaceTests implements TestInterface {
class TripleNestedInheritedCfgAndTestInterfaceTests implements TestInterface {
@Autowired
@Qualifier("foo")
@@ -0,0 +1,261 @@
/*
* Copyright 2002-present 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
*
* https://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.nested;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.ContextHierarchy;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.aot.DisabledInAotMode;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
/**
* Integration tests that verify support for {@code @Nested} test classes using
* {@link ContextHierarchy @ContextHierarchy} in conjunction with the
* {@link SpringExtension} in a JUnit Jupiter environment with
* {@link ExtensionContextScope#TEST_METHOD}.
*
* @author Sam Brannen
* @since 6.2.13
*/
class ContextHierarchyTestMethodScopedExtensionContextNestedTests {
private static final String FOO = "foo";
private static final String BAR = "bar";
private static final String BAZ = "baz";
private static final String QUX = "qux";
@Test
void runTests() {
EngineTestKit.engine("junit-jupiter")
.configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
.selectors(selectClass(TestCase.class))
.execute()
.testEvents()
.assertStatistics(stats -> stats.started(5).succeeded(5).failed(0));
}
@ExtendWith(SpringExtension.class)
@ContextHierarchy(@ContextConfiguration(classes = ParentConfig.class))
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
@DisabledInAotMode("@ContextHierarchy is not supported in AOT")
static class TestCase {
@Autowired
String foo;
@Autowired
ApplicationContext context;
@Test
void topLevelTest() {
assertThat(this.context).as("local ApplicationContext").isNotNull();
assertThat(this.context.getParent()).as("parent ApplicationContext").isNull();
assertThat(foo).isEqualTo(FOO);
}
@Nested
@ContextConfiguration(classes = NestedConfig.class)
class NestedTestCase {
@Autowired
String bar;
@Autowired
ApplicationContext context;
@Test
void nestedTest() {
assertThat(this.context).as("local ApplicationContext").isNotNull();
assertThat(this.context.getParent()).as("parent ApplicationContext").isNull();
// The foo field in the outer instance should have been injected from
// the test ApplicationContext for NestedTestCase.
assertThat(foo).isEqualTo(BAR);
assertThat(this.bar).isEqualTo(BAR);
}
}
@Nested
@NestedTestConfiguration(INHERIT)
@ContextConfiguration(classes = Child1Config.class)
class NestedInheritedCfgTestCase {
@Autowired
String bar;
@Autowired
ApplicationContext context;
@Test
void nestedTest() {
assertThat(this.context).as("local ApplicationContext").isNotNull();
assertThat(this.context.getParent()).as("parent ApplicationContext").isNotNull();
// The foo field in the outer instance and the bar field in the inner
// instance should both have been injected from the test ApplicationContext
// for the inner instance.
assertThat(foo).as("foo")
.isEqualTo(this.context.getBean("foo", String.class))
.isEqualTo(QUX + 1);
assertThat(this.bar).isEqualTo(BAZ + 1);
}
@Nested
@NestedTestConfiguration(OVERRIDE)
@ContextHierarchy({
@ContextConfiguration(classes = ParentConfig.class),
@ContextConfiguration(classes = Child2Config.class)
})
class DoubleNestedOverriddenCfgTestCase {
@Autowired
String bar;
@Autowired
ApplicationContext context;
@Test
void nestedTest() {
assertThat(this.context).as("local ApplicationContext").isNotNull();
assertThat(this.context.getParent()).as("parent ApplicationContext").isNotNull();
assertThat(foo).as("foo")
.isEqualTo(this.context.getBean("foo", String.class))
.isEqualTo(QUX + 2);
assertThat(this.bar).isEqualTo(BAZ + 2);
}
@Nested
@NestedTestConfiguration(INHERIT)
class TripleNestedInheritedCfgAndTestInterfaceTestCase implements TestInterface {
@Autowired
@Qualifier("foo")
String localFoo;
@Autowired
String bar;
@Autowired
ApplicationContext context;
@Test
void nestedTest() {
assertThat(this.context).as("local ApplicationContext").isNotNull();
assertThat(this.context.getParent()).as("parent ApplicationContext").isNotNull();
assertThat(this.context.getParent().getParent()).as("grandparent ApplicationContext").isNotNull();
assertThat(foo).as("foo")
.isEqualTo(this.localFoo)
.isEqualTo(this.context.getBean("foo", String.class))
.isEqualTo("test interface");
assertThat(this.bar).isEqualTo(BAZ + 2);
}
}
}
}
}
// -------------------------------------------------------------------------
@Configuration
static class ParentConfig {
@Bean
String foo() {
return FOO;
}
}
@Configuration
static class Child1Config {
@Bean
String foo() {
return QUX + 1;
}
@Bean
String bar() {
return BAZ + 1;
}
}
@Configuration
static class Child2Config {
@Bean
String foo() {
return QUX + 2;
}
@Bean
String bar() {
return BAZ + 2;
}
}
@Configuration
static class NestedConfig {
@Bean
String bar() {
return BAR;
}
}
@Configuration
static class TestInterfaceConfig {
@Bean
String foo() {
return "test interface";
}
}
@ContextConfiguration(classes = TestInterfaceConfig.class)
interface TestInterface {
}
}
@@ -18,6 +18,7 @@ package org.springframework.test.context.junit.jupiter.nested;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -36,7 +37,8 @@ import static org.springframework.test.context.TestConstructor.AutowireMode.ANNO
/**
* Integration tests that verify support for {@code @Nested} test classes using
* {@link TestConstructor @TestConstructor} in conjunction with the
* {@link SpringExtension} in a JUnit Jupiter environment.
* {@link SpringExtension} in a JUnit Jupiter environment with test class
* {@link ExtensionContextScope}.
*
* @author Sam Brannen
* @since 5.3
@@ -44,9 +46,9 @@ import static org.springframework.test.context.TestConstructor.AutowireMode.ANNO
@SpringJUnitConfig
@TestConstructor(autowireMode = ALL)
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class TestConstructorNestedTests {
class TestConstructorTestClassScopedExtensionContextNestedTests {
TestConstructorNestedTests(String text) {
TestConstructorTestClassScopedExtensionContextNestedTests(String text) {
assertThat(text).isEqualTo("enigma");
}
@@ -0,0 +1,190 @@
/*
* Copyright 2002-present 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
*
* https://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.nested;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.TestConstructor;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
import static org.springframework.test.context.TestConstructor.AutowireMode.ALL;
import static org.springframework.test.context.TestConstructor.AutowireMode.ANNOTATED;
/**
* Integration tests that verify support for {@code @Nested} test classes using
* {@link TestConstructor @TestConstructor} in conjunction with the
* {@link SpringExtension} in a JUnit Jupiter environment with
* {@link ExtensionContextScope#TEST_METHOD}.
*
* @author Sam Brannen
* @since 6.2.13
*/
class TestConstructorTestMethodScopedExtensionContextNestedTests {
@Test
void runTests() {
EngineTestKit.engine("junit-jupiter")
.configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
.selectors(selectClass(TestCase.class))
.execute()
.testEvents()
.assertStatistics(stats -> stats.started(8).succeeded(8).failed(0));
}
@SpringJUnitConfig(Config.class)
@TestConstructor(autowireMode = ALL)
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
static class TestCase {
TestCase(String text) {
assertThat(text).isEqualTo("enigma");
}
@Test
void test() {
}
@Nested
@SpringJUnitConfig(Config.class)
@TestConstructor(autowireMode = ANNOTATED)
class ConfigOverriddenByDefaultTestCase {
@Autowired
ConfigOverriddenByDefaultTestCase(String text) {
assertThat(text).isEqualTo("enigma");
}
@Test
void test() {
}
}
@Nested
@NestedTestConfiguration(INHERIT)
class InheritedConfigTestCase {
InheritedConfigTestCase(String text) {
assertThat(text).isEqualTo("enigma");
}
@Test
void test() {
}
@Nested
class DoubleNestedWithImplicitlyInheritedConfigTestCase {
DoubleNestedWithImplicitlyInheritedConfigTestCase(String text) {
assertThat(text).isEqualTo("enigma");
}
@Test
void test() {
}
@Nested
class TripleNestedWithImplicitlyInheritedConfigTestCase {
TripleNestedWithImplicitlyInheritedConfigTestCase(String text) {
assertThat(text).isEqualTo("enigma");
}
@Test
void test() {
}
}
}
@Nested
@NestedTestConfiguration(OVERRIDE)
@SpringJUnitConfig(Config.class)
@TestConstructor(autowireMode = ANNOTATED)
class DoubleNestedWithOverriddenConfigTestCase {
DoubleNestedWithOverriddenConfigTestCase(@Autowired String text) {
assertThat(text).isEqualTo("enigma");
}
@Test
void test() {
}
@Nested
@NestedTestConfiguration(INHERIT)
class TripleNestedWithInheritedConfigTestCase {
@Autowired
TripleNestedWithInheritedConfigTestCase(String text) {
assertThat(text).isEqualTo("enigma");
}
@Test
void test() {
}
}
@Nested
@NestedTestConfiguration(INHERIT)
class TripleNestedWithInheritedConfigAndTestInterfaceTestCase implements TestInterface {
TripleNestedWithInheritedConfigAndTestInterfaceTestCase(String text) {
assertThat(text).isEqualTo("enigma");
}
@Test
void test() {
}
}
}
}
}
// -------------------------------------------------------------------------
@Configuration
static class Config {
@Bean
String text() {
return "enigma";
}
}
@TestConstructor(autowireMode = ALL)
interface TestInterface {
}
}
@@ -18,6 +18,7 @@ package org.springframework.test.context.junit.jupiter.nested;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
@@ -26,7 +27,7 @@ import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.context.junit.jupiter.nested.TestPropertySourceNestedTests.Config;
import org.springframework.test.context.junit.jupiter.nested.TestPropertySourceTestClassScopedExtensionContextNestedTests.Config;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
@@ -35,7 +36,8 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
/**
* Integration tests that verify support for {@code @Nested} test classes using
* {@link TestPropertySource @TestPropertySource} in conjunction with the
* {@link SpringExtension} in a JUnit Jupiter environment.
* {@link SpringExtension} in a JUnit Jupiter environment with test class
* {@link ExtensionContextScope}.
*
* @author Sam Brannen
* @since 5.3
@@ -43,7 +45,7 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
@SpringJUnitConfig(Config.class)
@TestPropertySource(properties = "p1 = v1")
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class TestPropertySourceNestedTests {
class TestPropertySourceTestClassScopedExtensionContextNestedTests {
@Autowired
Environment env1;
@@ -57,7 +59,7 @@ class TestPropertySourceNestedTests {
@Nested
@NestedTestConfiguration(INHERIT)
class InheritedConfigTests {
class InheritedCfgTests {
@Autowired
Environment env2;
@@ -93,7 +95,7 @@ class TestPropertySourceNestedTests {
@NestedTestConfiguration(INHERIT)
@TestPropertySource(properties = "p2a = v2a")
@TestPropertySource(properties = "p2b = v2b")
class InheritedAndExtendedConfigTests {
class InheritedAndExtendedCfgTests {
@Autowired
Environment env2;
@@ -113,7 +115,7 @@ class TestPropertySourceNestedTests {
@NestedTestConfiguration(OVERRIDE)
@SpringJUnitConfig(Config.class)
@TestPropertySource(properties = "p3 = v3")
class L3WithOverriddenConfigTests {
class L3OverriddenCfgTests {
@Autowired
Environment env3;
@@ -136,7 +138,7 @@ class TestPropertySourceNestedTests {
@Nested
@NestedTestConfiguration(INHERIT)
@TestPropertySource(properties = {"p3 = v34", "p4 = v4"}, inheritProperties = false)
class L4WithInheritedConfigButOverriddenTestPropertiesTests {
class L4InheritedCfgButOverriddenTestPropsTests {
@Autowired
Environment env4;
@@ -161,7 +163,7 @@ class TestPropertySourceNestedTests {
}
@Nested
class L5WithInheritedConfigAndTestInterfaceTests implements TestInterface {
class L5InheritedCfgAndTestInterfaceTests implements TestInterface {
@Autowired
Environment env5;
@@ -0,0 +1,198 @@
/*
* Copyright 2002-present 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
*
* https://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.nested;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
/**
* Integration tests that verify support for {@code @Nested} test classes using
* {@link TestPropertySource @TestPropertySource} in conjunction with the
* {@link SpringExtension} in a JUnit Jupiter environment with
* {@link ExtensionContextScope#TEST_METHOD}.
*
* @author Sam Brannen
* @since 6.2.13
*/
class TestPropertySourceTestMethodScopedExtensionContextNestedTests {
@Test
void runTests() {
EngineTestKit.engine("junit-jupiter")
.configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
.selectors(selectClass(TestCase.class))
.execute()
.testEvents()
.assertStatistics(stats -> stats.started(7).succeeded(7).failed(0));
}
@SpringJUnitConfig(Config.class)
@TestPropertySource(properties = "p1 = v1")
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
static class TestCase {
@Autowired
Environment env1;
@Test
void propertiesInEnvironment() {
assertThat(env1.getProperty("p1")).isEqualTo("v1");
}
@Nested
@NestedTestConfiguration(INHERIT)
class InheritedCfgTestCase {
@Autowired
Environment env2;
@Test
void propertiesInEnvironment() {
assertThat(env1).isSameAs(env2);
assertThat(env2.getProperty("p1")).isEqualTo("v1");
}
}
@Nested
@SpringJUnitConfig(Config.class)
@TestPropertySource(properties = "p2 = v2")
class ConfigOverriddenByDefaultTestCase {
@Autowired
Environment env2;
@Test
void propertiesInEnvironment() {
assertThat(env1).isSameAs(env2);
assertThat(env2.getProperty("p1")).isNull();
assertThat(env2.getProperty("p2")).isEqualTo("v2");
}
}
@Nested
@NestedTestConfiguration(INHERIT)
@TestPropertySource(properties = "p2a = v2a")
@TestPropertySource(properties = "p2b = v2b")
class InheritedAndExtendedCfgTestCase {
@Autowired
Environment env2;
@Test
void propertiesInEnvironment() {
assertThat(env1).isSameAs(env2);
assertThat(env2.getProperty("p1")).isEqualTo("v1");
assertThat(env2.getProperty("p2a")).isEqualTo("v2a");
assertThat(env2.getProperty("p2b")).isEqualTo("v2b");
}
@Nested
@NestedTestConfiguration(OVERRIDE)
@SpringJUnitConfig(Config.class)
@TestPropertySource(properties = "p3 = v3")
class L3OverriddenCfgTestCase {
@Autowired
Environment env3;
@Test
void propertiesInEnvironment() {
assertThat(env1).isSameAs(env2).isSameAs(env3);
assertThat(env3.getProperty("p1")).isNull();
assertThat(env3.getProperty("p2")).isNull();
assertThat(env3.getProperty("p3")).isEqualTo("v3");
}
@Nested
@NestedTestConfiguration(INHERIT)
@TestPropertySource(properties = {"p3 = v34", "p4 = v4"}, inheritProperties = false)
class L4InheritedCfgButOverriddenTestPropertiesTestCase {
@Autowired
Environment env4;
@Test
void propertiesInEnvironment() {
assertThat(env1).isSameAs(env2).isSameAs(env3).isSameAs(env4);
assertThat(env4.getProperty("p1")).isNull();
assertThat(env4.getProperty("p2")).isNull();
assertThat(env4.getProperty("p3")).isEqualTo("v34");
assertThat(env4.getProperty("p4")).isEqualTo("v4");
}
@Nested
class L5InheritedCfgAndTestInterfaceTestCase implements TestInterface {
@Autowired
Environment env5;
@Test
void propertiesInEnvironment() {
assertThat(env4).isSameAs(env5);
assertThat(env5.getProperty("p1")).isNull();
assertThat(env5.getProperty("p2")).isNull();
assertThat(env5.getProperty("p3")).isEqualTo("v34");
assertThat(env5.getProperty("p4")).isEqualTo("v4");
assertThat(env5.getProperty("foo")).isEqualTo("bar");
assertThat(env5.getProperty("enigma")).isEqualTo("42");
}
}
}
}
}
}
// -------------------------------------------------------------------------
@Configuration
static class Config {
/* no user beans required for these tests */
}
@TestPropertySource(properties = { "foo = bar", "enigma: 42" })
interface TestInterface {
}
}
@@ -40,7 +40,8 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
*
* @author Sam Brannen
* @since 5.0
* @see ConstructorInjectionNestedTests
* @see ConstructorInjectionTestClassScopedExtensionContextNestedTests
* @see ConstructorInjectionTestMethodScopedExtensionContextNestedTests
* @see org.springframework.test.context.junit4.nested.NestedTestsWithSpringRulesTests
*/
@SpringJUnitWebConfig(Config.class)
@@ -37,7 +37,8 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Sam Brannen
* @since 5.0
* @see org.springframework.test.context.junit.jupiter.nested.ContextConfigurationNestedTests
* @see org.springframework.test.context.junit.jupiter.nested.ContextConfigurationTestClassScopedExtensionContextNestedTests
* @see org.springframework.test.context.junit.jupiter.nested.ContextConfigurationTestMethodScopedExtensionContextNestedTests
*/
@RunWith(HierarchicalContextRunner.class)
@ContextConfiguration(classes = TopLevelConfig.class)