Skip to content

Commit 9f5c777

Browse files
committed
Dont register spy if one already exist and is primary - #7621
1 parent 14a90aa commit 9f5c777

File tree

3 files changed

+158
-8
lines changed

3 files changed

+158
-8
lines changed

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

+18-8
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,7 @@
1818

1919
import java.beans.PropertyDescriptor;
2020
import java.lang.reflect.Field;
21-
import java.util.Arrays;
22-
import java.util.HashMap;
23-
import java.util.Iterator;
24-
import java.util.LinkedHashMap;
25-
import java.util.LinkedHashSet;
26-
import java.util.Map;
27-
import java.util.Set;
28-
import java.util.TreeSet;
21+
import java.util.*;
2922

3023
import org.springframework.aop.scope.ScopedProxyUtils;
3124
import org.springframework.aop.support.AopUtils;
@@ -319,13 +312,30 @@ private void registerSpies(SpyDefinition definition, Field field,
319312
}
320313

321314
private void registerSpy(SpyDefinition definition, Field field, String beanName) {
315+
if (isAlreadyRegisteredAndIsPrimary(definition)) {
316+
// don't register this new spy since we already registered one which is primary
317+
return;
318+
}
319+
322320
this.spies.put(beanName, definition);
323321
this.beanNameRegistry.put(definition, beanName);
324322
if (field != null) {
325323
this.fieldRegistry.put(field, new RegisteredField(definition, beanName));
326324
}
327325
}
328326

327+
private boolean isAlreadyRegisteredAndIsPrimary(SpyDefinition definition) {
328+
if (this.beanNameRegistry.keySet().contains(definition)) {
329+
String existingBeanName = this.beanNameRegistry.get(definition);
330+
BeanDefinition existingBeanDefinition = ((ConfigurableListableBeanFactory) this.beanFactory)
331+
.getBeanDefinition(existingBeanName);
332+
if (existingBeanDefinition.isPrimary()) {
333+
return true;
334+
}
335+
}
336+
return false;
337+
}
338+
329339
protected Object createSpyIfNecessary(Object bean, String beanName)
330340
throws BeansException {
331341
SpyDefinition definition = this.spies.get(beanName);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.springframework.boot.test.mock.mockito;
2+
3+
import org.hamcrest.Matchers;
4+
import org.junit.Assert;
5+
import org.junit.Test;
6+
import org.junit.runner.RunWith;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.context.annotation.Configuration;
9+
import org.springframework.context.annotation.Primary;
10+
import org.springframework.stereotype.Component;
11+
import org.springframework.test.context.junit4.SpringRunner;
12+
13+
import static org.mockito.Mockito.doReturn;
14+
15+
/**
16+
* Created by lsiu on 2016-12-14.
17+
*/
18+
@RunWith(SpringRunner.class)
19+
public class SpyBeanOnInterfaceWithTwoBeanWithFirstBeanMarkWithPrimaryTest {
20+
21+
@Autowired
22+
private Config.InterfaceAConsumer consumer;
23+
24+
@SpyBean
25+
private Config.TheInterface instance;
26+
27+
@Test
28+
public void test() {
29+
doReturn("fromSpyBean").when(instance).giveMeAString();
30+
Assert.assertThat(consumer.getTheString(), Matchers.equalTo("fromSpyBean"));
31+
}
32+
33+
@Configuration
34+
static class Config {
35+
public interface TheInterface {
36+
String giveMeAString();
37+
}
38+
39+
@Primary
40+
@Component
41+
public static class ClassOne implements TheInterface {
42+
@Override
43+
public String giveMeAString() {
44+
return "fromClassOne";
45+
}
46+
}
47+
48+
@Component
49+
public static class ClassTwo implements TheInterface {
50+
51+
@Override
52+
public String giveMeAString() {
53+
return "fromClassTwo";
54+
}
55+
}
56+
57+
@Component
58+
public static class InterfaceAConsumer {
59+
private final TheInterface theInterface;
60+
61+
public InterfaceAConsumer(TheInterface interfaceA) {
62+
this.theInterface = interfaceA;
63+
}
64+
65+
String getTheString() {
66+
return theInterface.giveMeAString();
67+
}
68+
}
69+
}
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.springframework.boot.test.mock.mockito;
2+
3+
import org.hamcrest.Matchers;
4+
import org.junit.Assert;
5+
import org.junit.Test;
6+
import org.junit.runner.RunWith;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.context.annotation.Configuration;
9+
import org.springframework.context.annotation.Primary;
10+
import org.springframework.stereotype.Component;
11+
import org.springframework.test.context.junit4.SpringRunner;
12+
13+
import static org.mockito.Mockito.doReturn;
14+
15+
/**
16+
* Created by lsiu on 2016-12-14.
17+
*/
18+
@RunWith(SpringRunner.class)
19+
public class SpyBeanOnInterfaceWithTwoBeanWithSecondBeanMarkWithPrimaryTest {
20+
21+
@Autowired
22+
private Config.InterfaceAConsumer consumer;
23+
24+
@SpyBean
25+
private Config.TheInterface instance;
26+
27+
@Test
28+
public void test() {
29+
doReturn("fromSpyBean").when(instance).giveMeAString();
30+
Assert.assertThat(consumer.getTheString(), Matchers.equalTo("fromSpyBean"));
31+
}
32+
33+
@Configuration
34+
static class Config {
35+
public interface TheInterface {
36+
String giveMeAString();
37+
}
38+
39+
@Component
40+
public static class ClassOne implements TheInterface {
41+
@Override
42+
public String giveMeAString() {
43+
return "fromClassOne";
44+
}
45+
}
46+
47+
@Primary
48+
@Component
49+
public static class ClassTwo implements TheInterface {
50+
51+
@Override
52+
public String giveMeAString() {
53+
return "fromClassTwo";
54+
}
55+
}
56+
57+
@Component
58+
public static class InterfaceAConsumer {
59+
private final TheInterface theInterface;
60+
61+
public InterfaceAConsumer(TheInterface interfaceA) {
62+
this.theInterface = interfaceA;
63+
}
64+
65+
String getTheString() {
66+
return theInterface.giveMeAString();
67+
}
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)