Browse Source
As a follow up to the previous commit (31f8e12adb), 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
pull/32941/head
19 changed files with 1044 additions and 681 deletions
@ -0,0 +1,56 @@
@@ -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 { |
||||
} |
||||
@ -0,0 +1,120 @@
@@ -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"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,88 @@
@@ -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() { |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,113 @@
@@ -0,0 +1,113 @@
|
||||
/* |
||||
* 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.mockito; |
||||
|
||||
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.assertThat; |
||||
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 MockitoBean @MockitoBean} "by type" integration tests for failure scenarios. |
||||
* |
||||
* @author Simon Baslé |
||||
* @author Sam Brannen |
||||
* @since 6.2 |
||||
* @see MockitoBeanByTypeIntegrationTests |
||||
*/ |
||||
class FailingMockitoBeanByTypeIntegrationTests { |
||||
|
||||
@Test |
||||
void zeroCandidates() { |
||||
Class<?> testClass = ZeroCandidatesTestCase.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 = TooManyCandidatesTestCase.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 ZeroCandidatesTestCase { |
||||
|
||||
@MockitoBean |
||||
ExampleService example; |
||||
|
||||
@Test |
||||
void test() { |
||||
assertThat(example).isNotNull(); |
||||
} |
||||
|
||||
@Configuration |
||||
static class Config { |
||||
} |
||||
} |
||||
|
||||
@SpringJUnitConfig |
||||
static class TooManyCandidatesTestCase { |
||||
|
||||
@MockitoBean |
||||
ExampleService example; |
||||
|
||||
@Test |
||||
void test() { |
||||
assertThat(example).isNotNull(); |
||||
} |
||||
|
||||
@Configuration |
||||
static class Config { |
||||
|
||||
@Bean |
||||
ExampleService bean1() { |
||||
return new RealExampleService("1 Hello"); |
||||
} |
||||
|
||||
@Bean |
||||
ExampleService bean2() { |
||||
return new RealExampleService("2 Hello"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,112 @@
@@ -0,0 +1,112 @@
|
||||
/* |
||||
* 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.mockito; |
||||
|
||||
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.assertThat; |
||||
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 MockitoSpyBean @MockitoSpyBean} "by type" integration tests for failure scenarios. |
||||
* |
||||
* @author Sam Brannen |
||||
* @since 6.2 |
||||
* @see MockitoSpyBeanByTypeIntegrationTests |
||||
*/ |
||||
class FailingMockitoSpyBeanByTypeIntegrationTests { |
||||
|
||||
@Test |
||||
void zeroCandidates() { |
||||
Class<?> testClass = ZeroCandidatesTestCase.class; |
||||
EngineTestKitUtils.executeTestsForClass(testClass).assertThatEvents().haveExactly(1, |
||||
finishedWithFailure( |
||||
cause( |
||||
instanceOf(IllegalStateException.class), |
||||
message(""" |
||||
Unable to select a bean to override by wrapping: 0 bean instances found of \ |
||||
type %s (as required by annotated field '%s.example')""" |
||||
.formatted(ExampleService.class.getName(), testClass.getSimpleName()))))); |
||||
} |
||||
|
||||
@Test |
||||
void tooManyCandidates() { |
||||
Class<?> testClass = TooManyCandidatesTestCase.class; |
||||
EngineTestKitUtils.executeTestsForClass(testClass).assertThatEvents().haveExactly(1, |
||||
finishedWithFailure( |
||||
cause( |
||||
instanceOf(IllegalStateException.class), |
||||
message(""" |
||||
Unable to select a bean to override by wrapping: 2 bean instances found of \ |
||||
type %s (as required by annotated field '%s.example')""" |
||||
.formatted(ExampleService.class.getName(), testClass.getSimpleName()))))); |
||||
} |
||||
|
||||
|
||||
@SpringJUnitConfig |
||||
static class ZeroCandidatesTestCase { |
||||
|
||||
@MockitoSpyBean |
||||
ExampleService example; |
||||
|
||||
@Test |
||||
void test() { |
||||
assertThat(example).isNotNull(); |
||||
} |
||||
|
||||
@Configuration |
||||
static class Config { |
||||
} |
||||
} |
||||
|
||||
@SpringJUnitConfig |
||||
static class TooManyCandidatesTestCase { |
||||
|
||||
@MockitoSpyBean |
||||
ExampleService example; |
||||
|
||||
@Test |
||||
void test() { |
||||
assertThat(example).isNotNull(); |
||||
} |
||||
|
||||
@Configuration |
||||
static class Config { |
||||
|
||||
@Bean |
||||
ExampleService bean1() { |
||||
return new RealExampleService("1 Hello"); |
||||
} |
||||
|
||||
@Bean |
||||
ExampleService bean2() { |
||||
return new RealExampleService("2 Hello"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,87 @@
@@ -0,0 +1,87 @@
|
||||
/* |
||||
* 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.mockito; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.test.context.bean.override.example.ExampleService; |
||||
import org.springframework.test.context.junit.EngineTestKitUtils; |
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; |
||||
|
||||
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 MockitoSpyBean @MockitoSpyBean} integration tests for failure scenarios. |
||||
* |
||||
* @author Simon Baslé |
||||
* @author Sam Brannen |
||||
* @since 6.2 |
||||
* @see MockitoSpyBeanIntegrationTests |
||||
*/ |
||||
class FailingMockitoSpyBeanIntegrationTests { |
||||
|
||||
@Test |
||||
void failWhenBeanNotPresentByType() { |
||||
Class<?> testClass = BeanNotPresentByTypeTestCase.class; |
||||
EngineTestKitUtils.executeTestsForClass(testClass).assertThatEvents().haveExactly(1, |
||||
finishedWithFailure( |
||||
cause(instanceOf(IllegalStateException.class), |
||||
message(""" |
||||
Unable to select a bean to override by wrapping: 0 bean instances found \ |
||||
of type %s (as required by annotated field '%s.notPresent')""" |
||||
.formatted(ExampleService.class.getName(), testClass.getSimpleName()))))); |
||||
} |
||||
|
||||
@Test |
||||
void failWhenBeanNotPresentByExplicitName() { |
||||
Class<?> testClass = BeanNotPresentByExplicitNameTestCase.class; |
||||
EngineTestKitUtils.executeTestsForClass(testClass).assertThatEvents().haveExactly(1, |
||||
finishedWithFailure( |
||||
cause(instanceOf(IllegalStateException.class), |
||||
message(""" |
||||
Unable to override bean 'notPresentAtAll' by wrapping: \ |
||||
there is no existing bean instance with that name of type %s""" |
||||
.formatted(ExampleService.class.getName()))))); |
||||
} |
||||
|
||||
|
||||
@SpringJUnitConfig |
||||
static class BeanNotPresentByTypeTestCase { |
||||
|
||||
@MockitoSpyBean |
||||
ExampleService notPresent; |
||||
|
||||
@Test |
||||
void test() { |
||||
} |
||||
} |
||||
|
||||
@SpringJUnitConfig |
||||
static class BeanNotPresentByExplicitNameTestCase { |
||||
|
||||
@MockitoSpyBean(name = "notPresentAtAll") |
||||
ExampleService field; |
||||
|
||||
@Test |
||||
void test() { |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,135 @@
@@ -0,0 +1,135 @@
|
||||
/* |
||||
* 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.mockito; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
import org.mockito.Mockito; |
||||
|
||||
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.core.annotation.Order; |
||||
import org.springframework.test.context.bean.override.example.CustomQualifier; |
||||
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 static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatException; |
||||
import static org.mockito.ArgumentMatchers.anyInt; |
||||
import static org.mockito.BDDMockito.when; |
||||
import static org.mockito.Mockito.times; |
||||
import static org.mockito.Mockito.verify; |
||||
import static org.mockito.Mockito.verifyNoMoreInteractions; |
||||
|
||||
/** |
||||
* {@link MockitoBean @MockitoBean} "by type" integration tests for success scenarios. |
||||
* |
||||
* @author Simon Baslé |
||||
* @author Sam Brannen |
||||
* @since 6.2 |
||||
* @see FailingMockitoBeanByTypeIntegrationTests |
||||
*/ |
||||
@SpringJUnitConfig |
||||
public class MockitoBeanByTypeIntegrationTests { |
||||
|
||||
@MockitoBean |
||||
ExampleService anyNameForService; |
||||
|
||||
@MockitoBean |
||||
@Qualifier("prefer") |
||||
StringBuilder ambiguous; |
||||
|
||||
@MockitoBean |
||||
@CustomQualifier |
||||
StringBuilder ambiguousMeta; |
||||
|
||||
|
||||
@Test |
||||
void overrideIsFoundByType(ApplicationContext ctx) { |
||||
assertThat(this.anyNameForService) |
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isMock()).as("isMock").isTrue()) |
||||
.isSameAs(ctx.getBean("example")) |
||||
.isSameAs(ctx.getBean(ExampleService.class)); |
||||
|
||||
when(this.anyNameForService.greeting()).thenReturn("Mocked greeting"); |
||||
|
||||
assertThat(this.anyNameForService.greeting()).isEqualTo("Mocked greeting"); |
||||
verify(this.anyNameForService, times(1)).greeting(); |
||||
verifyNoMoreInteractions(this.anyNameForService); |
||||
} |
||||
|
||||
@Test |
||||
void overrideIsFoundByTypeAndDisambiguatedByQualifier(ApplicationContext ctx) { |
||||
assertThat(this.ambiguous) |
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isMock()).as("isMock").isTrue()) |
||||
.isSameAs(ctx.getBean("ambiguous2")); |
||||
|
||||
assertThatException() |
||||
.isThrownBy(() -> ctx.getBean(StringBuilder.class)) |
||||
.withMessageEndingWith("but found 2: ambiguous2,ambiguous1"); |
||||
|
||||
assertThat(this.ambiguous).isEmpty(); |
||||
assertThat(this.ambiguous.substring(0)).isNull(); |
||||
verify(this.ambiguous, times(1)).length(); |
||||
verify(this.ambiguous, times(1)).substring(anyInt()); |
||||
verifyNoMoreInteractions(this.ambiguous); |
||||
} |
||||
|
||||
@Test |
||||
void overrideIsFoundByTypeAndDisambiguatedByMetaQualifier(ApplicationContext ctx) { |
||||
assertThat(this.ambiguousMeta) |
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isMock()).as("isMock").isTrue()) |
||||
.isSameAs(ctx.getBean("ambiguous1")); |
||||
|
||||
assertThatException() |
||||
.isThrownBy(() -> ctx.getBean(StringBuilder.class)) |
||||
.withMessageEndingWith("but found 2: ambiguous2,ambiguous1"); |
||||
|
||||
assertThat(this.ambiguousMeta).isEmpty(); |
||||
assertThat(this.ambiguousMeta.substring(0)).isNull(); |
||||
verify(this.ambiguousMeta, times(1)).length(); |
||||
verify(this.ambiguousMeta, times(1)).substring(anyInt()); |
||||
verifyNoMoreInteractions(this.ambiguousMeta); |
||||
} |
||||
|
||||
|
||||
@Configuration |
||||
static class Config { |
||||
|
||||
@Bean("example") |
||||
ExampleService bean1() { |
||||
return new RealExampleService("Production hello"); |
||||
} |
||||
|
||||
@Bean("ambiguous1") |
||||
@Order(1) |
||||
@CustomQualifier |
||||
StringBuilder bean2() { |
||||
return new StringBuilder("bean2"); |
||||
} |
||||
|
||||
@Bean("ambiguous2") |
||||
@Order(2) |
||||
@Qualifier("prefer") |
||||
StringBuilder bean3() { |
||||
return new StringBuilder("bean3"); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,323 +0,0 @@
@@ -1,323 +0,0 @@
|
||||
/* |
||||
* 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.mockito; |
||||
|
||||
import org.junit.jupiter.api.Nested; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.platform.engine.TestExecutionResult; |
||||
import org.junit.platform.testkit.engine.EngineExecutionResults; |
||||
import org.junit.platform.testkit.engine.EngineTestKit; |
||||
import org.mockito.Mockito; |
||||
|
||||
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.core.annotation.Order; |
||||
import org.springframework.test.context.bean.override.example.CustomQualifier; |
||||
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 static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatException; |
||||
import static org.assertj.core.api.InstanceOfAssertFactories.THROWABLE; |
||||
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; |
||||
import static org.mockito.ArgumentMatchers.anyInt; |
||||
import static org.mockito.BDDMockito.when; |
||||
import static org.mockito.Mockito.times; |
||||
import static org.mockito.Mockito.verify; |
||||
import static org.mockito.Mockito.verifyNoMoreInteractions; |
||||
|
||||
public class MockitoByTypeIntegrationTests { |
||||
|
||||
@Nested |
||||
@SpringJUnitConfig(ConfigByType.class) |
||||
class Mock { |
||||
|
||||
@MockitoBean |
||||
ExampleService anyNameForService; |
||||
|
||||
@MockitoBean |
||||
@Qualifier("prefer") |
||||
StringBuilder ambiguous; |
||||
|
||||
@MockitoBean |
||||
@CustomQualifier |
||||
StringBuilder ambiguousMeta; |
||||
|
||||
@Test |
||||
void overrideIsFoundByType(ApplicationContext ctx) { |
||||
assertThat(this.anyNameForService) |
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isMock()) |
||||
.as("isMock").isTrue()) |
||||
.isSameAs(ctx.getBean("example")) |
||||
.isSameAs(ctx.getBean(ExampleService.class)); |
||||
|
||||
when(this.anyNameForService.greeting()).thenReturn("Mocked greeting"); |
||||
|
||||
assertThat(this.anyNameForService.greeting()).isEqualTo("Mocked greeting"); |
||||
verify(this.anyNameForService, times(1)).greeting(); |
||||
verifyNoMoreInteractions(this.anyNameForService); |
||||
} |
||||
|
||||
@Test |
||||
void overrideIsFoundByTypeAndDisambiguatedByQualifier(ApplicationContext ctx) { |
||||
assertThat(this.ambiguous) |
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isMock()) |
||||
.as("isMock").isTrue()) |
||||
.isSameAs(ctx.getBean("ambiguous2")); |
||||
|
||||
assertThatException().isThrownBy(() -> ctx.getBean(StringBuilder.class)) |
||||
.withMessageEndingWith("but found 2: ambiguous2,ambiguous1"); |
||||
|
||||
assertThat(this.ambiguous.length()).isZero(); |
||||
assertThat(this.ambiguous.substring(0)).isNull(); |
||||
verify(this.ambiguous, times(1)).length(); |
||||
verify(this.ambiguous, times(1)).substring(anyInt()); |
||||
verifyNoMoreInteractions(this.ambiguous); |
||||
} |
||||
|
||||
@Test |
||||
void overrideIsFoundByTypeAndDisambiguatedByMetaQualifier(ApplicationContext ctx) { |
||||
assertThat(this.ambiguousMeta) |
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isMock()) |
||||
.as("isMock").isTrue()) |
||||
.isSameAs(ctx.getBean("ambiguous1")); |
||||
|
||||
assertThatException().isThrownBy(() -> ctx.getBean(StringBuilder.class)) |
||||
.withMessageEndingWith("but found 2: ambiguous2,ambiguous1"); |
||||
|
||||
assertThat(this.ambiguousMeta.length()).isZero(); |
||||
assertThat(this.ambiguousMeta.substring(0)).isNull(); |
||||
verify(this.ambiguousMeta, times(1)).length(); |
||||
verify(this.ambiguousMeta, times(1)).substring(anyInt()); |
||||
verifyNoMoreInteractions(this.ambiguousMeta); |
||||
} |
||||
|
||||
@Test |
||||
void zeroCandidates() { |
||||
Class<?> caseClass = CaseNone.class; |
||||
EngineExecutionResults results = EngineTestKit.engine("junit-jupiter")//
|
||||
.selectors(selectClass(caseClass))//
|
||||
.execute(); |
||||
|
||||
assertThat(results.allEvents().failed().stream()).hasSize(1).first() |
||||
.satisfies(e -> assertThat(e.getRequiredPayload(TestExecutionResult.class) |
||||
.getThrowable()).get(THROWABLE) |
||||
.cause() |
||||
.isInstanceOf(IllegalStateException.class) |
||||
.hasMessage("Unable to select a bean definition to override, 0 bean definitions " + |
||||
"found of type %s (as required by annotated field '%s.example')", |
||||
ExampleService.class.getName(), caseClass.getSimpleName())); |
||||
} |
||||
|
||||
@Test |
||||
void tooManyCandidates() { |
||||
Class<?> caseClass = CaseTooMany.class; |
||||
EngineExecutionResults results = EngineTestKit.engine("junit-jupiter")//
|
||||
.selectors(selectClass(caseClass))//
|
||||
.execute(); |
||||
|
||||
assertThat(results.allEvents().failed().stream()).hasSize(1).first() |
||||
.satisfies(e -> assertThat(e.getRequiredPayload(TestExecutionResult.class) |
||||
.getThrowable()).get(THROWABLE) |
||||
.cause() |
||||
.isInstanceOf(IllegalStateException.class) |
||||
.hasMessage("Unable to select a bean definition to override, 2 bean definitions " + |
||||
"found of type %s (as required by annotated field '%s.example')", |
||||
ExampleService.class.getName(), caseClass.getSimpleName())); |
||||
} |
||||
|
||||
@SpringJUnitConfig(FailingNone.class) |
||||
static class CaseNone { |
||||
@MockitoBean |
||||
ExampleService example; |
||||
|
||||
@Test |
||||
void test() { |
||||
assertThat(example).isNotNull(); |
||||
} |
||||
} |
||||
|
||||
@SpringJUnitConfig(FailingTooMany.class) |
||||
static class CaseTooMany { |
||||
@MockitoBean |
||||
ExampleService example; |
||||
|
||||
@Test |
||||
void test() { |
||||
assertThat(example).isNotNull(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Nested |
||||
@SpringJUnitConfig(ConfigByType.class) |
||||
class Spy { |
||||
|
||||
@MockitoSpyBean |
||||
ExampleService anyNameForService; |
||||
|
||||
@MockitoSpyBean |
||||
@Qualifier("prefer") |
||||
StringBuilder ambiguous; |
||||
|
||||
@MockitoSpyBean |
||||
@CustomQualifier |
||||
StringBuilder ambiguousMeta; |
||||
|
||||
@Test |
||||
void overrideIsFoundByType(ApplicationContext ctx) { |
||||
assertThat(this.anyNameForService) |
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isSpy()) |
||||
.as("isSpy").isTrue()) |
||||
.isSameAs(ctx.getBean("example")) |
||||
.isSameAs(ctx.getBean(ExampleService.class)); |
||||
|
||||
assertThat(this.anyNameForService.greeting()).isEqualTo("Production hello"); |
||||
verify(this.anyNameForService, times(1)).greeting(); |
||||
verifyNoMoreInteractions(this.anyNameForService); |
||||
} |
||||
|
||||
@Test |
||||
void overrideIsFoundByTypeAndDisambiguatedByQualifier(ApplicationContext ctx) { |
||||
assertThat(this.ambiguous) |
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isSpy()) |
||||
.as("isSpy").isTrue()) |
||||
.isSameAs(ctx.getBean("ambiguous2")); |
||||
|
||||
assertThatException().isThrownBy(() -> ctx.getBean(StringBuilder.class)) |
||||
.withMessageEndingWith("but found 2: ambiguous1,ambiguous2"); |
||||
|
||||
assertThat(this.ambiguous.toString()).isEqualTo("bean3"); |
||||
assertThat(this.ambiguous.length()).isEqualTo(5); |
||||
verify(this.ambiguous, times(1)).length(); |
||||
verifyNoMoreInteractions(this.ambiguous); //mockito doesn't verify toString
|
||||
} |
||||
|
||||
@Test |
||||
void overrideIsFoundByTypeAndDisambiguatedByMetaQualifier(ApplicationContext ctx) { |
||||
assertThat(this.ambiguousMeta) |
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isSpy()) |
||||
.as("isSpy").isTrue()) |
||||
.isSameAs(ctx.getBean("ambiguous1")); |
||||
|
||||
assertThatException().isThrownBy(() -> ctx.getBean(StringBuilder.class)) |
||||
.withMessageEndingWith("but found 2: ambiguous1,ambiguous2"); |
||||
|
||||
assertThat(this.ambiguousMeta.toString()).isEqualTo("bean2"); |
||||
assertThat(this.ambiguousMeta.length()).isEqualTo(5); |
||||
verify(this.ambiguousMeta, times(1)).length(); |
||||
verifyNoMoreInteractions(this.ambiguousMeta); //mockito doesn't verify toString
|
||||
} |
||||
|
||||
@Test |
||||
void zeroCandidates() { |
||||
Class<?> caseClass = CaseNone.class; |
||||
EngineExecutionResults results = EngineTestKit.engine("junit-jupiter")//
|
||||
.selectors(selectClass(caseClass))//
|
||||
.execute(); |
||||
|
||||
assertThat(results.allEvents().failed().stream()).hasSize(1).first() |
||||
.satisfies(e -> assertThat(e.getRequiredPayload(TestExecutionResult.class) |
||||
.getThrowable()).get(THROWABLE) |
||||
.cause() |
||||
.isInstanceOf(IllegalStateException.class) |
||||
.hasMessage("Unable to select a bean definition to override, 0 bean definitions " + |
||||
"found of type %s (as required by annotated field '%s.example')", |
||||
ExampleService.class.getName(), caseClass.getSimpleName())); |
||||
} |
||||
|
||||
@Test |
||||
void tooManyCandidates() { |
||||
Class<?> caseClass = CaseTooMany.class; |
||||
EngineExecutionResults results = EngineTestKit.engine("junit-jupiter")//
|
||||
.selectors(selectClass(caseClass))//
|
||||
.execute(); |
||||
|
||||
assertThat(results.allEvents().failed().stream()).hasSize(1).first() |
||||
.satisfies(e -> assertThat(e.getRequiredPayload(TestExecutionResult.class) |
||||
.getThrowable()).get(THROWABLE) |
||||
.cause() |
||||
.isInstanceOf(IllegalStateException.class) |
||||
.hasMessage("Unable to select a bean definition to override, 2 bean definitions " + |
||||
"found of type %s (as required by annotated field '%s.example')", |
||||
ExampleService.class.getName(), caseClass.getSimpleName())); |
||||
} |
||||
|
||||
@SpringJUnitConfig(FailingNone.class) |
||||
static class CaseNone { |
||||
@MockitoBean |
||||
ExampleService example; |
||||
|
||||
@Test |
||||
void test() { |
||||
assertThat(example).isNotNull(); |
||||
} |
||||
} |
||||
|
||||
@SpringJUnitConfig(FailingTooMany.class) |
||||
static class CaseTooMany { |
||||
@MockitoBean |
||||
ExampleService example; |
||||
|
||||
@Test |
||||
void test() { |
||||
assertThat(example).isNotNull(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Configuration |
||||
static class ConfigByType { |
||||
@Bean("example") |
||||
ExampleService bean1() { |
||||
return new RealExampleService("Production hello"); |
||||
} |
||||
|
||||
@Bean("ambiguous1") |
||||
@Order(1) |
||||
@CustomQualifier |
||||
StringBuilder bean2() { |
||||
return new StringBuilder("bean2"); |
||||
} |
||||
|
||||
@Bean("ambiguous2") |
||||
@Order(2) |
||||
@Qualifier("prefer") |
||||
StringBuilder bean3() { |
||||
return new StringBuilder("bean3"); |
||||
} |
||||
} |
||||
|
||||
@Configuration |
||||
static class FailingNone { |
||||
} |
||||
|
||||
@Configuration |
||||
static class FailingTooMany { |
||||
@Bean |
||||
ExampleService bean1() { |
||||
return new RealExampleService("1 Hello"); |
||||
} |
||||
@Bean |
||||
ExampleService bean2() { |
||||
return new RealExampleService("2 Hello"); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,129 @@
@@ -0,0 +1,129 @@
|
||||
/* |
||||
* 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.mockito; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
import org.mockito.Mockito; |
||||
|
||||
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.core.annotation.Order; |
||||
import org.springframework.test.context.bean.override.example.CustomQualifier; |
||||
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 static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatException; |
||||
import static org.mockito.Mockito.times; |
||||
import static org.mockito.Mockito.verify; |
||||
import static org.mockito.Mockito.verifyNoMoreInteractions; |
||||
|
||||
/** |
||||
* {@link MockitoSpyBean @MockitoSpyBean} "by type" integration tests for success scenarios. |
||||
* |
||||
* @author Simon Baslé |
||||
* @author Sam Brannen |
||||
* @since 6.2 |
||||
* @see FailingMockitoSpyBeanByTypeIntegrationTests |
||||
*/ |
||||
@SpringJUnitConfig |
||||
public class MockitoSpyBeanByTypeIntegrationTests { |
||||
|
||||
@MockitoSpyBean |
||||
ExampleService anyNameForService; |
||||
|
||||
@MockitoSpyBean |
||||
@Qualifier("prefer") |
||||
StringBuilder ambiguous; |
||||
|
||||
@MockitoSpyBean |
||||
@CustomQualifier |
||||
StringBuilder ambiguousMeta; |
||||
|
||||
|
||||
@Test |
||||
void overrideIsFoundByType(ApplicationContext ctx) { |
||||
assertThat(this.anyNameForService) |
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isSpy()).as("isSpy").isTrue()) |
||||
.isSameAs(ctx.getBean("example")) |
||||
.isSameAs(ctx.getBean(ExampleService.class)); |
||||
|
||||
assertThat(this.anyNameForService.greeting()).isEqualTo("Production hello"); |
||||
verify(this.anyNameForService, times(1)).greeting(); |
||||
verifyNoMoreInteractions(this.anyNameForService); |
||||
} |
||||
|
||||
@Test |
||||
void overrideIsFoundByTypeAndDisambiguatedByQualifier(ApplicationContext ctx) { |
||||
assertThat(this.ambiguous) |
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isSpy()).as("isSpy").isTrue()) |
||||
.isSameAs(ctx.getBean("ambiguous2")); |
||||
|
||||
assertThatException() |
||||
.isThrownBy(() -> ctx.getBean(StringBuilder.class)) |
||||
.withMessageEndingWith("but found 2: ambiguous1,ambiguous2"); |
||||
|
||||
assertThat(this.ambiguous.toString()).isEqualTo("bean3"); |
||||
assertThat(this.ambiguous.length()).isEqualTo(5); |
||||
verify(this.ambiguous, times(1)).length(); |
||||
verifyNoMoreInteractions(this.ambiguous); //mockito doesn't verify toString
|
||||
} |
||||
|
||||
@Test |
||||
void overrideIsFoundByTypeAndDisambiguatedByMetaQualifier(ApplicationContext ctx) { |
||||
assertThat(this.ambiguousMeta) |
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isSpy()).as("isSpy").isTrue()) |
||||
.isSameAs(ctx.getBean("ambiguous1")); |
||||
|
||||
assertThatException() |
||||
.isThrownBy(() -> ctx.getBean(StringBuilder.class)) |
||||
.withMessageEndingWith("but found 2: ambiguous1,ambiguous2"); |
||||
|
||||
assertThat(this.ambiguousMeta.toString()).isEqualTo("bean2"); |
||||
assertThat(this.ambiguousMeta.length()).isEqualTo(5); |
||||
verify(this.ambiguousMeta, times(1)).length(); |
||||
verifyNoMoreInteractions(this.ambiguousMeta); //mockito doesn't verify toString
|
||||
} |
||||
|
||||
|
||||
@Configuration |
||||
static class Config { |
||||
|
||||
@Bean("example") |
||||
ExampleService bean1() { |
||||
return new RealExampleService("Production hello"); |
||||
} |
||||
|
||||
@Bean("ambiguous1") |
||||
@Order(1) |
||||
@CustomQualifier |
||||
StringBuilder bean2() { |
||||
return new StringBuilder("bean2"); |
||||
} |
||||
|
||||
@Bean("ambiguous2") |
||||
@Order(2) |
||||
@Qualifier("prefer") |
||||
StringBuilder bean3() { |
||||
return new StringBuilder("bean3"); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
/* |
||||
* 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.junit; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
import org.assertj.core.api.Assertions; |
||||
import org.assertj.core.api.Condition; |
||||
import org.junit.platform.testkit.engine.EngineTestKit; |
||||
import org.junit.platform.testkit.engine.Events; |
||||
|
||||
import static java.util.stream.Collectors.toList; |
||||
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; |
||||
|
||||
/** |
||||
* Utilities for tests that use JUnit's {@link EngineTestKit}. |
||||
* |
||||
* @author Sam Brannen |
||||
* @since 6.2 |
||||
*/ |
||||
public class EngineTestKitUtils { |
||||
|
||||
public static Events executeTestsForClass(Class<?> testClass) { |
||||
return EngineTestKit.engine("junit-jupiter") |
||||
.selectors(selectClass(testClass)) |
||||
.execute() |
||||
.testEvents(); |
||||
} |
||||
|
||||
@SafeVarargs |
||||
@SuppressWarnings("varargs") |
||||
public static Condition<Throwable> rootCause(Condition<Throwable>... conditions) { |
||||
List<Condition<Throwable>> list = Arrays.stream(conditions) |
||||
.map(EngineTestKitUtils::rootCause) |
||||
.collect(toList()); |
||||
|
||||
return Assertions.allOf(list); |
||||
} |
||||
|
||||
private static Condition<Throwable> rootCause(Condition<Throwable> condition) { |
||||
return new Condition<>(throwable -> condition.matches(getRootCause(throwable)), |
||||
"throwable root cause matches %s", condition); |
||||
} |
||||
|
||||
private static Throwable getRootCause(Throwable throwable) { |
||||
Throwable cause = throwable.getCause(); |
||||
if (cause == null) { |
||||
return throwable; |
||||
} |
||||
return getRootCause(cause); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue