Skip to content
This repository was archived by the owner on Mar 8, 2019. It is now read-only.

Commit a5814d4

Browse files
author
Colin Shine
committed
Fix failing test for Issue #5724
1 parent 54ae778 commit a5814d4

File tree

4 files changed

+135
-0
lines changed

4 files changed

+135
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.springframework.boot.test.mock.mockito;
2+
3+
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
4+
import org.springframework.context.ConfigurableApplicationContext;
5+
import org.springframework.test.context.ContextCustomizer;
6+
import org.springframework.test.context.MergedContextConfiguration;
7+
8+
import java.util.Set;
9+
10+
public class MockitoScopedProxyContextCustomizer implements ContextCustomizer {
11+
12+
private final Set<Class> mockedTypes;
13+
14+
public MockitoScopedProxyContextCustomizer(Set<Class> mockedTypes) {
15+
this.mockedTypes = mockedTypes;
16+
}
17+
18+
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
19+
MockitoScopedProxyPostProcessor.register((BeanDefinitionRegistry) context, mockedTypes);
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.springframework.boot.test.mock.mockito;
2+
3+
import org.springframework.test.context.ContextConfigurationAttributes;
4+
import org.springframework.test.context.ContextCustomizer;
5+
import org.springframework.test.context.ContextCustomizerFactory;
6+
7+
import java.util.HashSet;
8+
import java.util.List;
9+
import java.util.Set;
10+
11+
public class MockitoScopedProxyContextCustomizerFactory implements ContextCustomizerFactory {
12+
13+
public ContextCustomizer createContextCustomizer(Class<?> testClass,
14+
List<ContextConfigurationAttributes> configAttributes) {
15+
DefinitionsParser parser = new DefinitionsParser();
16+
parser.parse(testClass);
17+
return new MockitoScopedProxyContextCustomizer(getMockAndSpyTypes(parser));
18+
}
19+
20+
private static Set<Class> getMockAndSpyTypes(DefinitionsParser parser) {
21+
Set<Class> mockAndSpyTypes = new HashSet<>();
22+
23+
for (Definition mockDef : parser.getDefinitions()) {
24+
if (mockDef instanceof MockDefinition) {
25+
mockAndSpyTypes.add(((MockDefinition) mockDef).getClassToMock());
26+
}
27+
if (mockDef instanceof SpyDefinition) {
28+
mockAndSpyTypes.add(((SpyDefinition) mockDef).getClassToSpy());
29+
}
30+
}
31+
32+
return mockAndSpyTypes;
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package org.springframework.boot.test.mock.mockito;
2+
3+
import org.springframework.beans.BeansException;
4+
import org.springframework.beans.factory.config.BeanDefinition;
5+
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
6+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
7+
import org.springframework.beans.factory.config.ConstructorArgumentValues;
8+
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
9+
import org.springframework.beans.factory.support.RootBeanDefinition;
10+
import org.springframework.core.Ordered;
11+
12+
import java.util.LinkedHashSet;
13+
import java.util.Set;
14+
15+
public class MockitoScopedProxyPostProcessor implements BeanFactoryPostProcessor, Ordered {
16+
17+
private static final String BEAN_NAME = MockitoScopedProxyPostProcessor.class.getName();
18+
public static final String SCOPED_TARGET_PREFIX = "scopedTarget.";
19+
20+
private final Set<Class> mockedTypes;
21+
22+
public MockitoScopedProxyPostProcessor(Set<Class> mockedTypes) {
23+
this.mockedTypes = mockedTypes;
24+
}
25+
26+
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
27+
BeanDefinitionRegistry bdr = (BeanDefinitionRegistry) beanFactory;
28+
29+
for (Class mockedType : mockedTypes) {
30+
String[] mockedBeans = beanFactory.getBeanNamesForType(mockedType);
31+
32+
for (String mockedBean : mockedBeans) {
33+
if (isScopedProxy(mockedBean)) {
34+
bdr.removeBeanDefinition(mockedBean);
35+
}
36+
}
37+
}
38+
}
39+
40+
private static boolean isScopedProxy(String mockedBean) {
41+
return mockedBean.startsWith(SCOPED_TARGET_PREFIX);
42+
}
43+
44+
public static void register(BeanDefinitionRegistry registry, Set<Class> mockedTypes) {
45+
BeanDefinition definition = getOrAddBeanDefinition(registry);
46+
47+
if (mockedTypes != null) {
48+
getConstructorArgs(definition).addAll(mockedTypes);
49+
}
50+
}
51+
52+
@SuppressWarnings("unchecked")
53+
private static Set<Class> getConstructorArgs(BeanDefinition definition) {
54+
ConstructorArgumentValues.ValueHolder constructorArg = definition.getConstructorArgumentValues()
55+
.getIndexedArgumentValue(0, Set.class);
56+
return (Set<Class>) constructorArg.getValue();
57+
}
58+
59+
private static BeanDefinition getOrAddBeanDefinition(BeanDefinitionRegistry registry) {
60+
if (!registry.containsBeanDefinition(BEAN_NAME)) {
61+
addBeanDefinition(registry);
62+
}
63+
64+
return registry.getBeanDefinition(BEAN_NAME);
65+
}
66+
67+
private static void addBeanDefinition(BeanDefinitionRegistry registry) {
68+
RootBeanDefinition def = new RootBeanDefinition(MockitoScopedProxyPostProcessor.class);
69+
def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
70+
ConstructorArgumentValues constructorArguments = def.getConstructorArgumentValues();
71+
constructorArguments.addIndexedArgumentValue(0, new LinkedHashSet<Class>());
72+
registry.registerBeanDefinition(BEAN_NAME, def);
73+
}
74+
75+
public int getOrder() {
76+
return Ordered.HIGHEST_PRECEDENCE;
77+
}
78+
}

Diff for: gh-5724/src/test/resources/META-INF/spring.factories

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
org.springframework.test.context.ContextCustomizerFactory=\
2+
org.springframework.boot.test.mock.mockito.MockitoScopedProxyContextCustomizerFactory

0 commit comments

Comments
 (0)