Browse Source
Historically, @Autowired fields in an enclosing class of a @Nested
test class have been injected from the ApplicationContext for the
enclosing class. If the enclosing test class and @Nested test class
share the same ApplicationContext configuration, things work as
developers expect. However, if the enclosing class and @Nested test
class have different ApplicationContexts, that can lead to
difficult-to-debug scenarios. For example, a bean injected into the
enclosing test class will not participate in a test-managed transaction
in the @Nested test class (see gh-34576).
JUnit Jupiter 5.12 introduced a new ExtensionContextScope feature which
allows the SpringExtension to behave the same for @Autowired fields as
it already does for @Autowired arguments in lifecycle and test
methods. Specifically, if a developer sets the ExtensionContextScope to
TEST_METHOD — for example, by configuring the following configuration
parameter as a JVM system property or in a `junit-platform.properties`
file — the SpringExtension already supports dependency injection from
the current, @Nested ApplicationContext in @Autowired fields in an
enclosing class of the @Nested test class.
junit.jupiter.extensions.testinstantiation.extensioncontextscope.default=test_method
However, there are two scenarios that fail as of Spring Framework
6.2.12.
1. @TestConstructor configuration in @Nested class hierarchies.
2. Field injection for bean overrides (such as @MockitoBean) in
@Nested class hierarchies.
Commit 82c34f7b51 fixed the SpringExtension to support scenario #2
above.
To fix scenario #1, this commit revises
BeanOverrideTestExecutionListener's injectField() implementation to
look up the fields to inject for the "current test instance" instead of
for the "current test class".
This commit also introduces tests for both scenarios.
See gh-34576
See gh-35676
Closes gh-35680
pull/35687/head
21 changed files with 1859 additions and 43 deletions
@ -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"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -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"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -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"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -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 { |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -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"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -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 { |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -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 { |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -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 { |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -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 { |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue