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"); + } + } + +}