Skip to content

Commit cd25a64

Browse files
committed
Merge branch '6.2.x'
2 parents 78f28fd + cd60a00 commit cd25a64

File tree

6 files changed

+133
-175
lines changed

6 files changed

+133
-175
lines changed

spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideContextCustomizerFactory.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.springframework.test.context.ContextConfigurationAttributes;
2525
import org.springframework.test.context.ContextCustomizerFactory;
2626
import org.springframework.test.context.TestContextAnnotationUtils;
27+
import org.springframework.util.Assert;
2728

2829
/**
2930
* {@link ContextCustomizerFactory} implementation that provides support for
@@ -51,10 +52,13 @@ public BeanOverrideContextCustomizer createContextCustomizer(Class<?> testClass,
5152
}
5253

5354
private void findBeanOverrideHandler(Class<?> testClass, Set<BeanOverrideHandler> handlers) {
54-
handlers.addAll(BeanOverrideHandler.forTestClass(testClass));
5555
if (TestContextAnnotationUtils.searchEnclosingClass(testClass)) {
5656
findBeanOverrideHandler(testClass.getEnclosingClass(), handlers);
5757
}
58+
BeanOverrideHandler.forTestClass(testClass).forEach(handler ->
59+
Assert.state(handlers.add(handler), () ->
60+
"Duplicate BeanOverrideHandler discovered in test class %s: %s"
61+
.formatted(testClass.getName(), handler)));
5862
}
5963

6064
}

spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideContextCustomizerFactoryTests.java

+25-6
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,20 @@
1919
import java.util.Collections;
2020
import java.util.function.Consumer;
2121

22-
import org.junit.jupiter.api.Nested;
2322
import org.junit.jupiter.api.Test;
2423

2524
import org.springframework.lang.Nullable;
2625
import org.springframework.test.context.bean.override.DummyBean.DummyBeanOverrideProcessor.DummyBeanOverrideHandler;
2726

2827
import static org.assertj.core.api.Assertions.assertThat;
28+
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
2929

3030
/**
3131
* Tests for {@link BeanOverrideContextCustomizerFactory}.
3232
*
3333
* @author Stephane Nicoll
34+
* @author Sam Brannen
35+
* @since 6.2
3436
*/
3537
class BeanOverrideContextCustomizerFactoryTests {
3638

@@ -65,6 +67,15 @@ void createContextCustomizerWhenNestedTestHasBeanOverrideAsWellAsTheParent() {
6567
.hasSize(2);
6668
}
6769

70+
@Test // gh-34054
71+
void failsWithDuplicateBeanOverrides() {
72+
Class<?> testClass = DuplicateOverridesTestCase.class;
73+
assertThatIllegalStateException()
74+
.isThrownBy(() -> createContextCustomizer(testClass))
75+
.withMessageStartingWith("Duplicate BeanOverrideHandler discovered in test class " + testClass.getName())
76+
.withMessageContaining("DummyBeanOverrideHandler");
77+
}
78+
6879

6980
private Consumer<BeanOverrideHandler> dummyHandler(@Nullable String beanName, Class<?> beanType) {
7081
return dummyHandler(beanName, beanType, BeanOverrideStrategy.REPLACE);
@@ -80,33 +91,41 @@ private Consumer<BeanOverrideHandler> dummyHandler(@Nullable String beanName, Cl
8091
}
8192

8293
@Nullable
83-
BeanOverrideContextCustomizer createContextCustomizer(Class<?> testClass) {
94+
private BeanOverrideContextCustomizer createContextCustomizer(Class<?> testClass) {
8495
return this.factory.createContextCustomizer(testClass, Collections.emptyList());
8596
}
8697

98+
8799
static class Test1 {
88100

89101
@DummyBean
90102
private String descriptor;
91-
92103
}
93104

94105
static class Test2 {
95106

96107
@DummyBean
97108
private String name;
98109

99-
@Nested
110+
// @Nested
100111
class Orange {
101112
}
102113

103-
@Nested
114+
// @Nested
104115
class Green {
105116

106117
@DummyBean(beanName = "counterBean")
107118
private Integer counter;
108-
109119
}
110120
}
111121

122+
static class DuplicateOverridesTestCase {
123+
124+
@DummyBean(beanName = "text")
125+
String text1;
126+
127+
@DummyBean(beanName = "text")
128+
String text2;
129+
}
130+
112131
}

spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanForByNameLookupIntegrationTests.java

+41-40
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,9 @@ public class TestBeanForByNameLookupIntegrationTests {
4040
@TestBean(name = "field")
4141
String field;
4242

43-
@TestBean(name = "nestedField")
44-
String nestedField;
45-
46-
@TestBean(name = "field")
47-
String renamed1;
48-
49-
@TestBean(name = "nestedField")
50-
String renamed2;
51-
5243
@TestBean(name = "methodRenamed1", methodName = "field")
5344
String methodRenamed1;
5445

55-
@TestBean(name = "methodRenamed2", methodName = "nestedField")
56-
String methodRenamed2;
57-
5846
static String field() {
5947
return "fieldOverride";
6048
}
@@ -66,62 +54,75 @@ static String nestedField() {
6654
@Test
6755
void fieldHasOverride(ApplicationContext ctx) {
6856
assertThat(ctx.getBean("field")).as("applicationContext").isEqualTo("fieldOverride");
69-
assertThat(this.field).as("injection point").isEqualTo("fieldOverride");
70-
}
71-
72-
@Test
73-
void renamedFieldHasOverride(ApplicationContext ctx) {
74-
assertThat(ctx.getBean("field")).as("applicationContext").isEqualTo("fieldOverride");
75-
assertThat(this.renamed1).as("injection point").isEqualTo("fieldOverride");
57+
assertThat(field).as("injection point").isEqualTo("fieldOverride");
7658
}
7759

7860
@Test
7961
void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
8062
assertThat(ctx.getBean("methodRenamed1")).as("applicationContext").isEqualTo("fieldOverride");
81-
assertThat(this.methodRenamed1).as("injection point").isEqualTo("fieldOverride");
63+
assertThat(methodRenamed1).as("injection point").isEqualTo("fieldOverride");
8264
}
8365

8466

8567
@Nested
86-
@DisplayName("With @TestBean in enclosing class")
68+
@DisplayName("With @TestBean in enclosing class and in @Nested class")
8769
public class TestBeanFieldInEnclosingClassTests {
8870

71+
@TestBean(name = "nestedField")
72+
String nestedField;
73+
74+
@TestBean(name = "methodRenamed2", methodName = "nestedField")
75+
String methodRenamed2;
76+
77+
8978
@Test
9079
void fieldHasOverride(ApplicationContext ctx) {
91-
assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
92-
assertThat(nestedField).isEqualTo("nestedFieldOverride");
80+
assertThat(ctx.getBean("field")).as("applicationContext").isEqualTo("fieldOverride");
81+
assertThat(field).as("injection point").isEqualTo("fieldOverride");
82+
}
83+
84+
@Test
85+
void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
86+
assertThat(ctx.getBean("methodRenamed1")).as("applicationContext").isEqualTo("fieldOverride");
87+
assertThat(methodRenamed1).as("injection point").isEqualTo("fieldOverride");
9388
}
9489

9590
@Test
96-
void renamedFieldHasOverride(ApplicationContext ctx) {
91+
void nestedFieldHasOverride(ApplicationContext ctx) {
9792
assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
98-
assertThat(renamed2).isEqualTo("nestedFieldOverride");
93+
assertThat(nestedField).isEqualTo("nestedFieldOverride");
9994
}
10095

10196
@Test
102-
void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
97+
void nestedFieldWithMethodNameHasOverride(ApplicationContext ctx) {
10398
assertThat(ctx.getBean("methodRenamed2")).as("applicationContext").isEqualTo("nestedFieldOverride");
10499
assertThat(methodRenamed2).isEqualTo("nestedFieldOverride");
105100
}
106101

107102
@Nested
108-
@DisplayName("With @TestBean in the enclosing class of the enclosing class")
103+
@DisplayName("With @TestBean in the enclosing classes")
109104
public class TestBeanFieldInEnclosingClassLevel2Tests {
110105

111106
@Test
112107
void fieldHasOverride(ApplicationContext ctx) {
113-
assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
114-
assertThat(nestedField).isEqualTo("nestedFieldOverride");
108+
assertThat(ctx.getBean("field")).as("applicationContext").isEqualTo("fieldOverride");
109+
assertThat(field).as("injection point").isEqualTo("fieldOverride");
110+
}
111+
112+
@Test
113+
void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
114+
assertThat(ctx.getBean("methodRenamed1")).as("applicationContext").isEqualTo("fieldOverride");
115+
assertThat(methodRenamed1).as("injection point").isEqualTo("fieldOverride");
115116
}
116117

117118
@Test
118-
void renamedFieldHasOverride(ApplicationContext ctx) {
119+
void nestedFieldHasOverride(ApplicationContext ctx) {
119120
assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
120-
assertThat(renamed2).isEqualTo("nestedFieldOverride");
121+
assertThat(nestedField).isEqualTo("nestedFieldOverride");
121122
}
122123

123124
@Test
124-
void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
125+
void nestedFieldWithMethodNameHasOverride(ApplicationContext ctx) {
125126
assertThat(ctx.getBean("methodRenamed2")).as("applicationContext").isEqualTo("nestedFieldOverride");
126127
assertThat(methodRenamed2).isEqualTo("nestedFieldOverride");
127128
}
@@ -133,25 +134,25 @@ void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
133134
public class TestBeanFactoryMethodInEnclosingClassTests {
134135

135136
@TestBean(methodName = "nestedField", name = "nestedField")
136-
String nestedField2;
137+
String nestedField;
137138

138139
@Test
139-
void fieldHasOverride(ApplicationContext ctx) {
140+
void nestedFieldHasOverride(ApplicationContext ctx) {
140141
assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
141-
assertThat(this.nestedField2).isEqualTo("nestedFieldOverride");
142+
assertThat(nestedField).isEqualTo("nestedFieldOverride");
142143
}
143144

144145
@Nested
145146
@DisplayName("With factory method in the enclosing class of the enclosing class")
146147
public class TestBeanFactoryMethodInEnclosingClassLevel2Tests {
147148

148-
@TestBean(methodName = "nestedField", name = "nestedField")
149-
String nestedField2;
149+
@TestBean(methodName = "nestedField", name = "nestedNestedField")
150+
String nestedNestedField;
150151

151152
@Test
152-
void fieldHasOverride(ApplicationContext ctx) {
153-
assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
154-
assertThat(this.nestedField2).isEqualTo("nestedFieldOverride");
153+
void nestedFieldHasOverride(ApplicationContext ctx) {
154+
assertThat(ctx.getBean("nestedNestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
155+
assertThat(nestedNestedField).isEqualTo("nestedFieldOverride");
155156
}
156157
}
157158
}

spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanForByNameLookupIntegrationTests.java

+50-24
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import org.junit.jupiter.api.Nested;
2121
import org.junit.jupiter.api.Test;
2222

23+
import org.springframework.beans.factory.annotation.Autowired;
24+
import org.springframework.beans.factory.annotation.Qualifier;
2325
import org.springframework.context.ApplicationContext;
2426
import org.springframework.context.annotation.Bean;
2527
import org.springframework.context.annotation.Configuration;
@@ -32,71 +34,95 @@
3234

3335
/**
3436
* Integration tests for {@link MockitoBean} that use by-name lookup.
37+
*
38+
* @author Simon Baslé
39+
* @author Sam Brannen
40+
* @since 6.2
3541
*/
3642
@SpringJUnitConfig
3743
public class MockitoBeanForByNameLookupIntegrationTests {
3844

3945
@MockitoBean("field")
4046
ExampleService field;
4147

42-
@MockitoBean("nestedField")
43-
ExampleService nestedField;
44-
45-
@MockitoBean("field")
46-
ExampleService renamed1;
47-
48-
@MockitoBean("nestedField")
49-
ExampleService renamed2;
50-
5148
@MockitoBean("nonExistingBean")
52-
ExampleService nonExisting1;
53-
54-
@MockitoBean("nestedNonExistingBean")
55-
ExampleService nonExisting2;
49+
ExampleService nonExisting;
5650

5751

5852
@Test
5953
void fieldAndRenamedFieldHaveSameOverride(ApplicationContext ctx) {
6054
assertThat(ctx.getBean("field"))
6155
.isInstanceOf(ExampleService.class)
6256
.satisfies(MockitoAssertions::assertIsMock)
63-
.isSameAs(this.field)
64-
.isSameAs(this.renamed1);
57+
.isSameAs(field);
6558

66-
assertThat(this.field.greeting()).as("mocked greeting").isNull();
67-
assertThat(this.renamed1.greeting()).as("mocked greeting").isNull();
59+
assertThat(field.greeting()).as("mocked greeting").isNull();
6860
}
6961

7062
@Test
7163
void fieldIsMockedWhenNoOriginalBean(ApplicationContext ctx) {
7264
assertThat(ctx.getBean("nonExistingBean"))
7365
.isInstanceOf(ExampleService.class)
7466
.satisfies(MockitoAssertions::assertIsMock)
75-
.isSameAs(this.nonExisting1);
67+
.isSameAs(nonExisting);
7668

77-
assertThat(this.nonExisting1.greeting()).as("mocked greeting").isNull();
69+
assertThat(nonExisting.greeting()).as("mocked greeting").isNull();
7870
}
7971

8072

8173
@Nested
82-
@DisplayName("With @MockitoBean in enclosing class")
74+
@DisplayName("With @MockitoBean in enclosing class and in @Nested class")
8375
public class MockitoBeanNestedTests {
8476

77+
@Autowired
78+
@Qualifier("field")
79+
ExampleService localField;
80+
81+
@Autowired
82+
@Qualifier("nonExistingBean")
83+
ExampleService localNonExisting;
84+
85+
@MockitoBean("nestedField")
86+
ExampleService nestedField;
87+
88+
@MockitoBean("nestedNonExistingBean")
89+
ExampleService nestedNonExisting;
90+
91+
8592
@Test
8693
void fieldAndRenamedFieldHaveSameOverride(ApplicationContext ctx) {
87-
assertThat(ctx.getBean("nestedField"))
94+
assertThat(ctx.getBean("field"))
8895
.isInstanceOf(ExampleService.class)
8996
.satisfies(MockitoAssertions::assertIsMock)
90-
.isSameAs(nestedField)
91-
.isSameAs(renamed2);
97+
.isSameAs(localField);
98+
99+
assertThat(localField.greeting()).as("mocked greeting").isNull();
92100
}
93101

94102
@Test
95103
void fieldIsMockedWhenNoOriginalBean(ApplicationContext ctx) {
104+
assertThat(ctx.getBean("nonExistingBean"))
105+
.isInstanceOf(ExampleService.class)
106+
.satisfies(MockitoAssertions::assertIsMock)
107+
.isSameAs(localNonExisting);
108+
109+
assertThat(localNonExisting.greeting()).as("mocked greeting").isNull();
110+
}
111+
112+
@Test
113+
void nestedFieldAndRenamedFieldHaveSameOverride(ApplicationContext ctx) {
114+
assertThat(ctx.getBean("nestedField"))
115+
.isInstanceOf(ExampleService.class)
116+
.satisfies(MockitoAssertions::assertIsMock)
117+
.isSameAs(nestedField);
118+
}
119+
120+
@Test
121+
void nestedFieldIsMockedWhenNoOriginalBean(ApplicationContext ctx) {
96122
assertThat(ctx.getBean("nestedNonExistingBean"))
97123
.isInstanceOf(ExampleService.class)
98124
.satisfies(MockitoAssertions::assertIsMock)
99-
.isSameAs(nonExisting2);
125+
.isSameAs(nestedNonExisting);
100126
}
101127
}
102128

0 commit comments

Comments
 (0)