-
Notifications
You must be signed in to change notification settings - Fork 38.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revise bean override tests with a focus on AOT support
As a follow up to the previous commit (31f8e12), this commit polishes bean override tests and revises them with a focus on AOT testing support and simplified maintenance. - Introduce EngineTestKitUtils to simplify working with JUnit's EngineTestKit. - Use idiomatic EngineTestKit APIs to simplify assertions on EngineTestKit results. - Introduce BeanOverrideTestSuite to simplify running all bean override tests within the IDE. - Separate failure and success scenario tests, so that failure tests do not launch the JUnit Platform to run tests using the Spring TestContext Framework (TCF) within a test class that itself uses the TCF. - Make AbstractTestBeanIntegrationTestCase actually abstract. - Rename test case classes to give them meaningful names and simplify understanding of what's being tested. - Ensure tests for @MockitoSpyBean functionality use @MockitoSpyBean instead of @MockitoBean. - Declare @Configuration classes local to @SpringJUnitConfig test classes whenever possible. See gh-29122 See gh-32925
- Loading branch information
Showing
19 changed files
with
1,044 additions
and
681 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
...t/src/test/java/org/springframework/test/context/bean/override/BeanOverrideTestSuite.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright 2002-2024 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; | ||
|
||
import org.junit.jupiter.api.ClassOrderer; | ||
import org.junit.platform.suite.api.ConfigurationParameter; | ||
import org.junit.platform.suite.api.ExcludeTags; | ||
import org.junit.platform.suite.api.IncludeClassNamePatterns; | ||
import org.junit.platform.suite.api.IncludeEngines; | ||
import org.junit.platform.suite.api.SelectPackages; | ||
import org.junit.platform.suite.api.Suite; | ||
|
||
/** | ||
* JUnit Platform based test suite for tests that involve bean override support | ||
* in the Spring TestContext Framework. | ||
* | ||
* <p><strong>This suite is only intended to be used manually within an IDE.</strong> | ||
* | ||
* <h3>Logging Configuration</h3> | ||
* | ||
* <p>In order for our log4j2 configuration to be used in an IDE, you must | ||
* set the following system property before running any tests — for | ||
* example, in <em>Run Configurations</em> in Eclipse. | ||
* | ||
* <pre style="code"> | ||
* -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager | ||
* </pre> | ||
* | ||
* @author Sam Brannen | ||
* @since 6.2 | ||
*/ | ||
@Suite | ||
@IncludeEngines("junit-jupiter") | ||
@SelectPackages("org.springframework.test.context.bean.override") | ||
@IncludeClassNamePatterns(".*Tests$") | ||
@ExcludeTags("failing-test-case") | ||
@ConfigurationParameter( | ||
key = ClassOrderer.DEFAULT_ORDER_PROPERTY_NAME, | ||
value = "org.junit.jupiter.api.ClassOrderer$ClassName" | ||
) | ||
public class BeanOverrideTestSuite { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
...ramework/test/context/bean/override/convention/FailingTestBeanByTypeIntegrationTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
/* | ||
* Copyright 2002-2024 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.Test; | ||
|
||
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.EngineTestKitUtils; | ||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; | ||
|
||
import static org.assertj.core.api.Assertions.fail; | ||
import static org.junit.platform.testkit.engine.EventConditions.finishedWithFailure; | ||
import static org.junit.platform.testkit.engine.TestExecutionResultConditions.cause; | ||
import static org.junit.platform.testkit.engine.TestExecutionResultConditions.instanceOf; | ||
import static org.junit.platform.testkit.engine.TestExecutionResultConditions.message; | ||
|
||
/** | ||
* {@link TestBean @TestBean} "by type" integration tests for failure scenarios. | ||
* | ||
* @author Simon Baslé | ||
* @author Sam Brannen | ||
* @since 6.2 | ||
* @see TestBeanByTypeIntegrationTests | ||
*/ | ||
class FailingTestBeanByTypeIntegrationTests { | ||
|
||
@Test | ||
void zeroCandidates() { | ||
Class<?> testClass = NoMatchingBeansTestCase.class; | ||
EngineTestKitUtils.executeTestsForClass(testClass).assertThatEvents().haveExactly(1, | ||
finishedWithFailure( | ||
cause( | ||
instanceOf(IllegalStateException.class), | ||
message(""" | ||
Unable to select a bean definition to override: 0 bean definitions \ | ||
found of type %s (as required by annotated field '%s.example')""" | ||
.formatted(ExampleService.class.getName(), testClass.getSimpleName()))))); | ||
} | ||
|
||
@Test | ||
void tooManyCandidates() { | ||
Class<?> testClass = TooManyBeansTestCase.class; | ||
EngineTestKitUtils.executeTestsForClass(testClass).assertThatEvents().haveExactly(1, | ||
finishedWithFailure( | ||
cause( | ||
instanceOf(IllegalStateException.class), | ||
message(""" | ||
Unable to select a bean definition to override: 2 bean definitions \ | ||
found of type %s (as required by annotated field '%s.example')""" | ||
.formatted(ExampleService.class.getName(), testClass.getSimpleName()))))); | ||
} | ||
|
||
|
||
@SpringJUnitConfig | ||
static class NoMatchingBeansTestCase { | ||
|
||
@TestBean | ||
ExampleService example; | ||
|
||
@Test | ||
void test() { | ||
} | ||
|
||
static ExampleService exampleTestOverride() { | ||
return fail("unexpected override"); | ||
} | ||
|
||
@Configuration | ||
static class Config { | ||
} | ||
} | ||
|
||
|
||
@SpringJUnitConfig | ||
static class TooManyBeansTestCase { | ||
|
||
@TestBean | ||
ExampleService example; | ||
|
||
@Test | ||
void test() { | ||
} | ||
|
||
static ExampleService exampleTestOverride() { | ||
return fail("unexpected override"); | ||
} | ||
|
||
@Configuration | ||
static class Config { | ||
|
||
@Bean | ||
ExampleService bean1() { | ||
return new RealExampleService("1 Hello"); | ||
} | ||
|
||
@Bean | ||
ExampleService bean2() { | ||
return new RealExampleService("2 Hello"); | ||
} | ||
} | ||
} | ||
|
||
} |
88 changes: 88 additions & 0 deletions
88
...ork/test/context/bean/override/convention/FailingTestBeanInheritanceIntegrationTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* Copyright 2002-2024 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.Test; | ||
|
||
import org.springframework.test.context.junit.EngineTestKitUtils; | ||
|
||
import static org.junit.platform.testkit.engine.EventConditions.finishedWithFailure; | ||
import static org.junit.platform.testkit.engine.TestExecutionResultConditions.instanceOf; | ||
import static org.junit.platform.testkit.engine.TestExecutionResultConditions.message; | ||
import static org.springframework.test.context.junit.EngineTestKitUtils.rootCause; | ||
|
||
/** | ||
* {@link TestBean @TestBean} inheritance integration tests for failure scenarios. | ||
* | ||
* @author Simon Baslé | ||
* @author Sam Brannen | ||
* @since 6.2 | ||
* @see TestBeanInheritanceIntegrationTests | ||
*/ | ||
class FailingTestBeanInheritanceIntegrationTests { | ||
|
||
@Test | ||
void failsIfFieldInSupertypeButNoMethod() { | ||
Class<?> testClass = FieldInSupertypeButNoMethodTestCase.class; | ||
EngineTestKitUtils.executeTestsForClass(testClass).assertThatEvents().haveExactly(1, | ||
finishedWithFailure( | ||
rootCause( | ||
instanceOf(IllegalStateException.class), | ||
message(""" | ||
Failed to find a static test bean factory method in %s with return type %s \ | ||
whose name matches one of the supported candidates [someBeanTestOverride]""" | ||
.formatted(testClass.getName(), AbstractTestBeanIntegrationTestCase.Pojo.class.getName()))))); | ||
} | ||
|
||
@Test | ||
void failsIfMethod1InSupertypeAndMethod2InType() { | ||
Class<?> testClass = Method1InSupertypeAndMethod2InTypeTestCase.class; | ||
EngineTestKitUtils.executeTestsForClass(testClass).assertThatEvents().haveExactly(1, | ||
finishedWithFailure( | ||
rootCause( | ||
instanceOf(IllegalStateException.class), | ||
message(""" | ||
Found 2 competing static test bean factory methods in %s with return type %s \ | ||
whose name matches one of the supported candidates \ | ||
[thirdBeanTestOverride, anotherBeanTestOverride]""" | ||
.formatted(testClass.getName(), AbstractTestBeanIntegrationTestCase.Pojo.class.getName()))))); | ||
} | ||
|
||
|
||
static class FieldInSupertypeButNoMethodTestCase extends AbstractTestBeanIntegrationTestCase { | ||
|
||
@Test | ||
void test() { | ||
} | ||
} | ||
|
||
static class Method1InSupertypeAndMethod2InTypeTestCase extends AbstractTestBeanIntegrationTestCase { | ||
|
||
static Pojo someBeanTestOverride() { | ||
return new FakePojo("ignored"); | ||
} | ||
|
||
static Pojo anotherBeanTestOverride() { | ||
return new FakePojo("sub2"); | ||
} | ||
|
||
@Test | ||
void test() { | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.