Skip to content

Commit f355080

Browse files
committed
Merge branch '3.2.x'
Closes gh-40855
2 parents fa07419 + 486ceec commit f355080

File tree

2 files changed

+95
-3
lines changed

2 files changed

+95
-3
lines changed

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoPostProcessor.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,8 @@ private Set<String> getExistingBeans(ConfigurableListableBeanFactory beanFactory
254254
Class<?> type = resolvableType.resolve(Object.class);
255255
for (String beanName : beanFactory.getBeanNamesForType(FactoryBean.class, true, false)) {
256256
beanName = BeanFactoryUtils.transformedBeanName(beanName);
257-
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
258-
Object attribute = beanDefinition.getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE);
259-
if (resolvableType.equals(attribute) || type.equals(attribute)) {
257+
Class<?> producedType = beanFactory.getType(beanName, false);
258+
if (type.equals(producedType)) {
260259
beans.add(beanName);
261260
}
262261
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright 2012-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.mock.mockito;
18+
19+
import org.junit.jupiter.api.Test;
20+
import org.junit.jupiter.api.extension.ExtendWith;
21+
import org.mockito.Mockito;
22+
23+
import org.springframework.beans.factory.FactoryBean;
24+
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
25+
import org.springframework.beans.factory.support.RootBeanDefinition;
26+
import org.springframework.boot.test.mock.mockito.example.ExampleGenericService;
27+
import org.springframework.boot.test.mock.mockito.example.SimpleExampleStringGenericService;
28+
import org.springframework.context.annotation.Configuration;
29+
import org.springframework.context.annotation.Import;
30+
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
31+
import org.springframework.core.ResolvableType;
32+
import org.springframework.core.type.AnnotationMetadata;
33+
import org.springframework.test.context.junit.jupiter.SpringExtension;
34+
35+
import static org.assertj.core.api.Assertions.assertThat;
36+
37+
/**
38+
* Test {@link SpyBean @SpyBean} on a test class field can be used to replace an existing
39+
* bean with generics that's produced by a factory bean.
40+
*
41+
* @author Andy Wilkinson
42+
*/
43+
@ExtendWith(SpringExtension.class)
44+
class SpyBeanOnTestFieldForExistingGenericBeanProducedByFactoryBeanIntegrationTests {
45+
46+
// gh-40234
47+
48+
@SpyBean(name = "exampleService")
49+
private ExampleGenericService<String> exampleService;
50+
51+
@Test
52+
void testSpying() {
53+
assertThat(Mockito.mockingDetails(this.exampleService).isSpy()).isTrue();
54+
assertThat(Mockito.mockingDetails(this.exampleService).getMockCreationSettings().getSpiedInstance())
55+
.isInstanceOf(SimpleExampleStringGenericService.class);
56+
}
57+
58+
@Configuration(proxyBeanMethods = false)
59+
@Import(FactoryBeanRegistrar.class)
60+
static class SpyBeanOnTestFieldForExistingBeanConfig {
61+
62+
}
63+
64+
static class FactoryBeanRegistrar implements ImportBeanDefinitionRegistrar {
65+
66+
@Override
67+
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
68+
BeanDefinitionRegistry registry) {
69+
RootBeanDefinition definition = new RootBeanDefinition(ExampleGenericServiceFactoryBean.class);
70+
definition.setTargetType(ResolvableType.forClassWithGenerics(ExampleGenericServiceFactoryBean.class, null,
71+
ExampleGenericService.class));
72+
registry.registerBeanDefinition("exampleService", definition);
73+
}
74+
75+
}
76+
77+
static class ExampleGenericServiceFactoryBean<T, U extends ExampleGenericService<T>> implements FactoryBean<U> {
78+
79+
@SuppressWarnings("unchecked")
80+
@Override
81+
public U getObject() throws Exception {
82+
return (U) new SimpleExampleStringGenericService();
83+
}
84+
85+
@Override
86+
@SuppressWarnings("rawtypes")
87+
public Class<ExampleGenericService> getObjectType() {
88+
return ExampleGenericService.class;
89+
}
90+
91+
}
92+
93+
}

0 commit comments

Comments
 (0)