From 7148b28b2bacffe85af9289d84aec46163950fc4 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Wed, 30 Oct 2024 10:22:15 +0100 Subject: [PATCH] Integration test Bean Override support for multiple candidate beans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit introduces integration tests which verify that Bean Overrides (for example, @⁠MockitoBean and @⁠MockitoSpyBean) can select a single candidate bean to override when there are multiple candidates that match the required type. To "select" the desired bean, these tests rely on one of the following. - explicit bean name in the bean override annotation - explicit @⁠Qualifier on the bean override field - explicit @⁠Primary on one of the candidate beans However, the @⁠Primary tests are currently @⁠Disabled until @⁠Primary is honored in the Spring TestContext Framework. See gh-33742 --- ...nsAndExplicitBeanNameIntegrationTests.java | 88 ++++++++++++++++++ ...sAndExplicitQualifierIntegrationTests.java | 90 ++++++++++++++++++ ...ingBeansAndOnePrimaryIntegrationTests.java | 91 +++++++++++++++++++ ...nsAndExplicitBeanNameIntegrationTests.java | 86 ++++++++++++++++++ ...sAndExplicitQualifierIntegrationTests.java | 88 ++++++++++++++++++ ...ingBeansAndOnePrimaryIntegrationTests.java | 89 ++++++++++++++++++ 6 files changed, 532 insertions(+) create mode 100644 spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests.java create mode 100644 spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests.java create mode 100644 spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests.java create mode 100644 spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoSpyBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests.java create mode 100644 spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoSpyBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests.java create mode 100644 spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoSpyBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests.java diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests.java new file mode 100644 index 00000000000..9029cca2ecc --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests.java @@ -0,0 +1,88 @@ +/* + * Copyright 2012-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.integration; + +import org.junit.jupiter.api.Test; +import org.mockito.MockingDetails; +import org.mockito.mock.MockCreationSettings; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.bean.override.example.ExampleGenericServiceCaller; +import org.springframework.test.context.bean.override.example.IntegerExampleGenericService; +import org.springframework.test.context.bean.override.example.StringExampleGenericService; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mockingDetails; + +/** + * Tests that {@link MockitoBean @MockitoBean} can be used to mock a bean when + * there are multiple candidates and an explicit bean name is supplied to select + * one of the candidates. + * + * @author Sam Brannen + * @author Phillip Webb + * @since 6.2 + * @see MockitoBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests + * @see MockitoBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests + */ +@SpringJUnitConfig +class MockitoBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests { + + @MockitoBean("stringService") + StringExampleGenericService mock; + + @Autowired + ExampleGenericServiceCaller caller; + + + @Test + void test() { + MockingDetails mockingDetails = mockingDetails(mock); + MockCreationSettings mockSettings = mockingDetails.getMockCreationSettings(); + assertThat(mockingDetails.isMock()).as("is mock").isTrue(); + assertThat(mockSettings.getMockName()).as("mock name").hasToString("stringService"); + + given(mock.greeting()).willReturn("mocked"); + assertThat(caller.sayGreeting()).isEqualTo("I say mocked 123"); + then(mock).should().greeting(); + } + + + @Configuration(proxyBeanMethods = false) + @Import({ ExampleGenericServiceCaller.class, IntegerExampleGenericService.class }) + static class Config { + + @Bean + StringExampleGenericService one() { + return new StringExampleGenericService("one"); + } + + @Bean + // "stringService" matches the constructor argument name in ExampleGenericServiceCaller + StringExampleGenericService stringService() { + return new StringExampleGenericService("two"); + } + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests.java new file mode 100644 index 00000000000..57df8f3014e --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests.java @@ -0,0 +1,90 @@ +/* + * Copyright 2012-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.integration; + +import org.junit.jupiter.api.Test; +import org.mockito.MockingDetails; +import org.mockito.mock.MockCreationSettings; + +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.context.annotation.Import; +import org.springframework.test.context.bean.override.example.ExampleGenericServiceCaller; +import org.springframework.test.context.bean.override.example.IntegerExampleGenericService; +import org.springframework.test.context.bean.override.example.StringExampleGenericService; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mockingDetails; + +/** + * Tests that {@link MockitoBean @MockitoBean} can be used to mock a bean when + * there are multiple candidates and a {@link Qualifier @Qualifier} is supplied + * to select one of the candidates. + * + * @author Sam Brannen + * @author Phillip Webb + * @since 6.2 + * @see MockitoBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests + * @see MockitoBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests + */ +@SpringJUnitConfig +class MockitoBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests { + + @Qualifier("stringService") + @MockitoBean + StringExampleGenericService mock; + + @Autowired + ExampleGenericServiceCaller caller; + + + @Test + void test() { + MockingDetails mockingDetails = mockingDetails(mock); + MockCreationSettings mockSettings = mockingDetails.getMockCreationSettings(); + assertThat(mockingDetails.isMock()).as("is mock").isTrue(); + assertThat(mockSettings.getMockName()).as("mock name").hasToString("stringService"); + + given(mock.greeting()).willReturn("mocked"); + assertThat(caller.sayGreeting()).isEqualTo("I say mocked 123"); + then(mock).should().greeting(); + } + + + @Configuration(proxyBeanMethods = false) + @Import({ ExampleGenericServiceCaller.class, IntegerExampleGenericService.class }) + static class Config { + + @Bean + StringExampleGenericService one() { + return new StringExampleGenericService("one"); + } + + @Bean + // "stringService" matches the constructor argument name in ExampleGenericServiceCaller + StringExampleGenericService stringService() { + return new StringExampleGenericService("two"); + } + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests.java new file mode 100644 index 00000000000..b3b8d6f1c10 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests.java @@ -0,0 +1,91 @@ +/* + * Copyright 2012-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.integration; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.MockingDetails; +import org.mockito.mock.MockCreationSettings; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Primary; +import org.springframework.test.context.bean.override.example.ExampleGenericServiceCaller; +import org.springframework.test.context.bean.override.example.IntegerExampleGenericService; +import org.springframework.test.context.bean.override.example.StringExampleGenericService; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mockingDetails; + +/** + * Tests that {@link MockitoBean @MockitoBean} can be used to mock a bean when + * there are multiple candidates and one is primary. + * + * @author Sam Brannen + * @author Phillip Webb + * @since 6.2 + * @see MockitoBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests + * @see MockitoBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests + */ +@Disabled("Disabled until @Primary is supported for BeanOverrideStrategy.REPLACE_OR_CREATE") +@ExtendWith(SpringExtension.class) +class MockitoBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests { + + @MockitoBean + StringExampleGenericService mock; + + @Autowired + ExampleGenericServiceCaller caller; + + + @Test + void test() { + MockingDetails mockingDetails = mockingDetails(mock); + MockCreationSettings mockSettings = mockingDetails.getMockCreationSettings(); + assertThat(mockingDetails.isMock()).as("is mock").isTrue(); + assertThat(mockSettings.getMockName()).as("mock name").hasToString("two"); + + given(mock.greeting()).willReturn("mocked"); + assertThat(caller.sayGreeting()).isEqualTo("I say mocked 123"); + then(mock).should().greeting(); + } + + + @Configuration(proxyBeanMethods = false) + @Import({ ExampleGenericServiceCaller.class, IntegerExampleGenericService.class }) + static class Config { + + @Bean + StringExampleGenericService one() { + return new StringExampleGenericService("one"); + } + + @Bean + @Primary + StringExampleGenericService two() { + return new StringExampleGenericService("two"); + } + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoSpyBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoSpyBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests.java new file mode 100644 index 00000000000..2e2358fdacf --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoSpyBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests.java @@ -0,0 +1,86 @@ +/* + * Copyright 2012-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.integration; + +import org.junit.jupiter.api.Test; +import org.mockito.MockingDetails; +import org.mockito.mock.MockCreationSettings; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.bean.override.example.ExampleGenericServiceCaller; +import org.springframework.test.context.bean.override.example.IntegerExampleGenericService; +import org.springframework.test.context.bean.override.example.StringExampleGenericService; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mockingDetails; + +/** + * Tests that {@link MockitoSpyBean @MockitoSpyBean} can be used to spy on a bean + * when there are multiple candidates and an explicit bean name is supplied to + * select one of the candidates. + * + * @author Sam Brannen + * @author Phillip Webb + * @since 6.2 + * @see MockitoSpyBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests + * @see MockitoSpyBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests + */ +@SpringJUnitConfig +class MockitoSpyBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests { + + @MockitoSpyBean("stringService") + StringExampleGenericService spy; + + @Autowired + ExampleGenericServiceCaller caller; + + + @Test + void test() { + MockingDetails mockingDetails = mockingDetails(spy); + MockCreationSettings mockSettings = mockingDetails.getMockCreationSettings(); + assertThat(mockingDetails.isSpy()).as("is spy").isTrue(); + assertThat(mockSettings.getMockName()).hasToString("stringService"); + + assertThat(caller.sayGreeting()).isEqualTo("I say two 123"); + then(spy).should().greeting(); + } + + + @Configuration(proxyBeanMethods = false) + @Import({ ExampleGenericServiceCaller.class, IntegerExampleGenericService.class }) + static class Config { + + @Bean + StringExampleGenericService one() { + return new StringExampleGenericService("one"); + } + + @Bean + // "stringService" matches the constructor argument name in ExampleGenericServiceCaller + StringExampleGenericService stringService() { + return new StringExampleGenericService("two"); + } + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoSpyBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoSpyBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests.java new file mode 100644 index 00000000000..b03f11f5b0f --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoSpyBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests.java @@ -0,0 +1,88 @@ +/* + * Copyright 2012-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.integration; + +import org.junit.jupiter.api.Test; +import org.mockito.MockingDetails; +import org.mockito.mock.MockCreationSettings; + +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.context.annotation.Import; +import org.springframework.test.context.bean.override.example.ExampleGenericServiceCaller; +import org.springframework.test.context.bean.override.example.IntegerExampleGenericService; +import org.springframework.test.context.bean.override.example.StringExampleGenericService; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mockingDetails; + +/** + * Tests that {@link MockitoSpyBean @MockitoSpyBean} can be used to spy on a bean + * when there are multiple candidates and a {@link Qualifier @Qualifier} is supplied + * to select one of the candidates. + * + * @author Sam Brannen + * @author Phillip Webb + * @since 6.2 + * @see MockitoSpyBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests + * @see MockitoSpyBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests + */ +@SpringJUnitConfig +class MockitoSpyBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests { + + @Qualifier("stringService") + @MockitoSpyBean + StringExampleGenericService spy; + + @Autowired + ExampleGenericServiceCaller caller; + + + @Test + void test() { + MockingDetails mockingDetails = mockingDetails(spy); + MockCreationSettings mockSettings = mockingDetails.getMockCreationSettings(); + assertThat(mockingDetails.isSpy()).as("is spy").isTrue(); + assertThat(mockSettings.getMockName()).hasToString("stringService"); + + assertThat(caller.sayGreeting()).isEqualTo("I say two 123"); + then(spy).should().greeting(); + } + + + @Configuration(proxyBeanMethods = false) + @Import({ ExampleGenericServiceCaller.class, IntegerExampleGenericService.class }) + static class Config { + + @Bean + StringExampleGenericService one() { + return new StringExampleGenericService("one"); + } + + @Bean + // "stringService" matches the constructor argument name in ExampleGenericServiceCaller + StringExampleGenericService stringService() { + return new StringExampleGenericService("two"); + } + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoSpyBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoSpyBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests.java new file mode 100644 index 00000000000..a0b1f33e1d2 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoSpyBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests.java @@ -0,0 +1,89 @@ +/* + * Copyright 2012-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.integration; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.MockingDetails; +import org.mockito.mock.MockCreationSettings; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Primary; +import org.springframework.test.context.bean.override.example.ExampleGenericServiceCaller; +import org.springframework.test.context.bean.override.example.IntegerExampleGenericService; +import org.springframework.test.context.bean.override.example.StringExampleGenericService; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mockingDetails; + +/** + * Tests that {@link MockitoSpyBean @MockitoSpyBean} can be used to spy on a bean + * when there are multiple candidates and one is {@link Primary @Primary}. + * + * @author Phillip Webb + * @author Sam Brannen + * @since 6.2 + * @see MockitoSpyBeanWithMultipleExistingBeansAndExplicitBeanNameIntegrationTests + * @see MockitoSpyBeanWithMultipleExistingBeansAndExplicitQualifierIntegrationTests + */ +@Disabled("Disabled until @Primary is supported for @MockitoSpyBean") +@ExtendWith(SpringExtension.class) +class MockitoSpyBeanWithMultipleExistingBeansAndOnePrimaryIntegrationTests { + + @MockitoSpyBean + StringExampleGenericService spy; + + @Autowired + ExampleGenericServiceCaller caller; + + + @Test + void testSpying() { + MockingDetails mockingDetails = mockingDetails(spy); + MockCreationSettings mockSettings = mockingDetails.getMockCreationSettings(); + assertThat(mockingDetails.isSpy()).as("is spy").isTrue(); + assertThat(mockSettings.getMockName()).hasToString("two"); + + assertThat(caller.sayGreeting()).isEqualTo("I say two 123"); + then(spy).should().greeting(); + } + + + @Configuration(proxyBeanMethods = false) + @Import({ ExampleGenericServiceCaller.class, IntegerExampleGenericService.class }) + static class Config { + + @Bean + StringExampleGenericService one() { + return new StringExampleGenericService("one"); + } + + @Bean + @Primary + StringExampleGenericService two() { + return new StringExampleGenericService("two"); + } + } + +}