diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanDuplicateTypeIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanDuplicateTypeIntegrationTests.java index 4ff6f624808..d00ead41963 100644 --- a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanDuplicateTypeIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanDuplicateTypeIntegrationTests.java @@ -33,6 +33,8 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Sam Brannen * @since 6.2.1 * @see gh-34025 + * @see MockitoSpyBeanDuplicateTypeIntegrationTests + * @see MockitoSpyBeanDuplicateTypeAndNameIntegrationTests */ @SpringJUnitConfig public class MockitoBeanDuplicateTypeIntegrationTests { diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanDuplicateTypeAndNameIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanDuplicateTypeAndNameIntegrationTests.java new file mode 100644 index 00000000000..e80c4d1ce4b --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanDuplicateTypeAndNameIntegrationTests.java @@ -0,0 +1,85 @@ +/* + * 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 java.util.List; + +import org.junit.jupiter.api.Test; +import org.mockito.MockingDetails; + +import org.springframework.beans.factory.annotation.Autowired; +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 static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mockingDetails; + +/** + * Integration tests for duplicate {@link MockitoSpyBean @MockitoSpyBean} + * declarations for the same target bean, selected by-name. + * + * @author Sam Brannen + * @since 6.2.1 + * @see MockitoBeanDuplicateTypeIntegrationTests + * @see MockitoSpyBeanDuplicateTypeIntegrationTests + */ +@SpringJUnitConfig +public class MockitoSpyBeanDuplicateTypeAndNameIntegrationTests { + + @MockitoSpyBean("exampleService1") + ExampleService service1; + + @MockitoSpyBean("exampleService1") + ExampleService service2; + + @Autowired + ExampleService exampleService2; + + @Autowired + List services; + + + @Test + void duplicateMocksShouldHaveBeenCreated() { + assertThat(service1).isSameAs(service2); + assertThat(services).containsExactly(service1, exampleService2); + + MockingDetails mockingDetails1 = mockingDetails(service1); + MockingDetails mockingDetails2 = mockingDetails(exampleService2); + assertThat(mockingDetails1.isSpy()).as("isSpy(service1)").isTrue(); + assertThat(mockingDetails2.isSpy()).as("isSpy(exampleService2)").isFalse(); + } + + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + ExampleService exampleService1() { + return new RealExampleService("@Bean 1"); + } + + @Bean + ExampleService exampleService2() { + return new RealExampleService("@Bean 2"); + } + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanDuplicateTypeIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanDuplicateTypeIntegrationTests.java new file mode 100644 index 00000000000..5312ede620e --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanDuplicateTypeIntegrationTests.java @@ -0,0 +1,75 @@ +/* + * 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 java.util.List; + +import org.junit.jupiter.api.Test; +import org.mockito.MockingDetails; + +import org.springframework.beans.factory.annotation.Autowired; +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 static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mockingDetails; + +/** + * Integration tests for duplicate {@link MockitoSpyBean @MockitoSpyBean} + * declarations for the same target bean, selected by-type. + * + * @author Sam Brannen + * @since 6.2.1 + * @see MockitoBeanDuplicateTypeIntegrationTests + * @see MockitoSpyBeanDuplicateTypeAndNameIntegrationTests + */ +@SpringJUnitConfig +public class MockitoSpyBeanDuplicateTypeIntegrationTests { + + @MockitoSpyBean + ExampleService service1; + + @MockitoSpyBean + ExampleService service2; + + @Autowired + List services; + + + @Test + void test() { + assertThat(service1).isSameAs(service2); + assertThat(services).containsExactly(service1); + + MockingDetails mockingDetails = mockingDetails(service1); + assertThat(mockingDetails.isSpy()).as("isSpy(field1)").isTrue(); + } + + + @Configuration(proxyBeanMethods = false) + static class Config { + + @Bean + ExampleService exampleService() { + return new RealExampleService("@Bean"); + } + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanForByNameLookupIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanForByNameLookupIntegrationTests.java index 1310a18d436..d230dccf671 100644 --- a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanForByNameLookupIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanForByNameLookupIntegrationTests.java @@ -35,80 +35,81 @@ import static org.assertj.core.api.Assertions.assertThat; * Integration tests for {@link MockitoSpyBean} that use by-name lookup. * * @author Simon Baslé + * @author Sam Brannen * @since 6.2 */ @SpringJUnitConfig(Config.class) public class MockitoSpyBeanForByNameLookupIntegrationTests { - @MockitoSpyBean("field") + @MockitoSpyBean("field1") ExampleService field; - @MockitoSpyBean("nestedField") - ExampleService nestedField; - - @MockitoSpyBean("field") + @MockitoSpyBean("field1") ExampleService renamed1; - @MockitoSpyBean("nestedField") - ExampleService renamed2; - @Test void fieldHasOverride(ApplicationContext ctx) { - assertThat(ctx.getBean("field")) + assertThat(ctx.getBean("field1")) .isInstanceOf(ExampleService.class) .satisfies(o -> assertThat(Mockito.mockingDetails(o).isSpy()).as("isSpy").isTrue()) - .isSameAs(this.field); + .isSameAs(field); - assertThat(this.field.greeting()).isEqualTo("Hello Field"); + assertThat(field.greeting()).isEqualTo("bean1"); } @Test void renamedFieldHasOverride(ApplicationContext ctx) { - assertThat(ctx.getBean("field")) + assertThat(ctx.getBean("field1")) .isInstanceOf(ExampleService.class) .satisfies(o -> assertThat(Mockito.mockingDetails(o).isSpy()).as("isSpy").isTrue()) - .isSameAs(this.renamed1); + .isSameAs(renamed1); - assertThat(this.renamed1.greeting()).isEqualTo("Hello Field"); + assertThat(renamed1.greeting()).isEqualTo("bean1"); } @Nested - @DisplayName("With @MockitoSpyBean in enclosing class") + @DisplayName("With @MockitoSpyBean in enclosing class and in @Nested class") public class MockitoSpyBeanNestedTests { + @MockitoSpyBean("field2") + ExampleService nestedField; + + @MockitoSpyBean("field2") + ExampleService renamed2; + @Test void fieldHasOverride(ApplicationContext ctx) { - assertThat(ctx.getBean("nestedField")) + assertThat(ctx.getBean("field2")) .isInstanceOf(ExampleService.class) .satisfies(o -> assertThat(Mockito.mockingDetails(o).isSpy()).as("isSpy").isTrue()) .isSameAs(nestedField); - assertThat(nestedField.greeting()).isEqualTo("Hello Nested Field"); + assertThat(nestedField.greeting()).isEqualTo("bean2"); } @Test void renamedFieldHasOverride(ApplicationContext ctx) { - assertThat(ctx.getBean("nestedField")) + assertThat(ctx.getBean("field2")) .isInstanceOf(ExampleService.class) .satisfies(o -> assertThat(Mockito.mockingDetails(o).isSpy()).as("isSpy").isTrue()) .isSameAs(renamed2); - assertThat(renamed2.greeting()).isEqualTo("Hello Nested Field"); + assertThat(renamed2.greeting()).isEqualTo("bean2"); } } @Configuration(proxyBeanMethods = false) static class Config { - @Bean("field") + @Bean("field1") ExampleService bean1() { - return new RealExampleService("Hello Field"); + return new RealExampleService("bean1"); } - @Bean("nestedField") + @Bean("field2") ExampleService bean2() { - return new RealExampleService("Hello Nested Field"); + return new RealExampleService("bean2"); } }