Skip to content

Commit 4a0edc5

Browse files
committed
Verify support for MockReset for beans within the ApplicationContext
This commit verifies that MockReset.before() and MockReset.after() are supported for beans within the ApplicationContext. However, the test class must declare a field annotated with either @⁠MockitoBean or @⁠MockitoSpyBean in order for the MockReset feature to be triggered. See gh-33742
1 parent c979edd commit 4a0edc5

File tree

2 files changed

+252
-0
lines changed

2 files changed

+252
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2012-2024 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.test.context.bean.override.mockito;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
/**
22+
* Integration tests for {@link MockitoResetTestExecutionListener} with a
23+
* {@link MockitoBean @MockitoBean} field.
24+
*
25+
* @author Sam Brannen
26+
* @since 6.2
27+
* @see MockitoResetTestExecutionListenerWithoutMockitoAnnotationsIntegrationTests
28+
*/
29+
class MockitoResetTestExecutionListenerWithMockitoBeanIntegrationTests
30+
extends MockitoResetTestExecutionListenerWithoutMockitoAnnotationsIntegrationTests {
31+
32+
// The following mock is not used but is currently required to trigger support for MockReset.
33+
@MockitoBean
34+
StringBuilder unusedVariable;
35+
36+
37+
@Test
38+
@Override
39+
void test002() {
40+
super.test002();
41+
}
42+
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/*
2+
* Copyright 2012-2024 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.test.context.bean.override.mockito;
18+
19+
import org.junit.jupiter.api.Disabled;
20+
import org.junit.jupiter.api.MethodOrderer;
21+
import org.junit.jupiter.api.Test;
22+
import org.junit.jupiter.api.TestMethodOrder;
23+
24+
import org.springframework.beans.factory.FactoryBean;
25+
import org.springframework.beans.factory.annotation.Autowired;
26+
import org.springframework.context.ApplicationContext;
27+
import org.springframework.context.annotation.Bean;
28+
import org.springframework.context.annotation.Configuration;
29+
import org.springframework.context.annotation.Lazy;
30+
import org.springframework.test.context.bean.override.example.ExampleService;
31+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
32+
33+
import static org.assertj.core.api.Assertions.assertThat;
34+
import static org.mockito.BDDMockito.given;
35+
import static org.mockito.Mockito.mock;
36+
37+
/**
38+
* Integration tests for {@link MockitoResetTestExecutionListener} without a
39+
* {@link MockitoBean @MockitoBean} or {@link MockitoSpyBean @MockitoSpyBean} field.
40+
*
41+
* @author Phillip Webb
42+
* @author Andy Wilkinson
43+
* @author Sam Brannen
44+
* @since 6.2
45+
* @see MockitoResetTestExecutionListenerWithMockitoBeanIntegrationTests
46+
*/
47+
@SpringJUnitConfig
48+
@TestMethodOrder(MethodOrderer.MethodName.class)
49+
class MockitoResetTestExecutionListenerWithoutMockitoAnnotationsIntegrationTests {
50+
51+
@Autowired
52+
ApplicationContext context;
53+
54+
55+
@Test
56+
void test001() {
57+
ExampleService nonSingletonFactoryBean = getMock("nonSingletonFactoryBean");
58+
59+
given(getMock("none").greeting()).willReturn("none");
60+
given(getMock("before").greeting()).willReturn("before");
61+
given(getMock("after").greeting()).willReturn("after");
62+
given(getMock("singletonFactoryBean").greeting()).willReturn("singletonFactoryBean");
63+
given(nonSingletonFactoryBean.greeting()).willReturn("nonSingletonFactoryBean");
64+
65+
assertThat(getMock("none").greeting()).isEqualTo("none");
66+
assertThat(getMock("before").greeting()).isEqualTo("before");
67+
assertThat(getMock("after").greeting()).isEqualTo("after");
68+
assertThat(getMock("singletonFactoryBean").greeting()).isEqualTo("singletonFactoryBean");
69+
70+
// The saved reference should have been mocked.
71+
assertThat(nonSingletonFactoryBean.greeting()).isEqualTo("nonSingletonFactoryBean");
72+
// A new reference should have not been mocked.
73+
assertThat(getMock("nonSingletonFactoryBean").greeting()).isNull();
74+
75+
// getMock("nonSingletonFactoryBean") has been invoked twice in this method.
76+
assertThat(context.getBean(NonSingletonFactoryBean.class).getObjectInvocations).isEqualTo(2);
77+
}
78+
79+
@Disabled("MockReset is currently only honored if @MockitoBean or @MockitoSpyBean is used")
80+
@Test
81+
void test002() {
82+
// Should not have been reset.
83+
assertThat(getMock("none").greeting()).isEqualTo("none");
84+
85+
// Should have been reset.
86+
assertThat(getMock("before").greeting()).isNull();
87+
assertThat(getMock("after").greeting()).isNull();
88+
assertThat(getMock("singletonFactoryBean").greeting()).isNull();
89+
90+
// A non-singleton FactoryBean always creates a new mock instance. Thus,
91+
// resetting is irrelevant, and the greeting should be null.
92+
assertThat(getMock("nonSingletonFactoryBean").greeting()).isNull();
93+
94+
// getMock("nonSingletonFactoryBean") has been invoked twice in test001()
95+
// and once in this method.
96+
assertThat(context.getBean(NonSingletonFactoryBean.class).getObjectInvocations).isEqualTo(3);
97+
}
98+
99+
private ExampleService getMock(String name) {
100+
return context.getBean(name, ExampleService.class);
101+
}
102+
103+
104+
@Configuration(proxyBeanMethods = false)
105+
static class Config {
106+
107+
@Bean
108+
ExampleService none() {
109+
return mock(ExampleService.class);
110+
}
111+
112+
@Bean
113+
ExampleService before() {
114+
return mock(ExampleService.class, MockReset.before());
115+
}
116+
117+
@Bean
118+
ExampleService after() {
119+
return mock(ExampleService.class, MockReset.after());
120+
}
121+
122+
@Bean
123+
@Lazy
124+
ExampleService fail() {
125+
// Spring Boot gh-5870
126+
throw new RuntimeException();
127+
}
128+
129+
@Bean
130+
BrokenFactoryBean brokenFactoryBean() {
131+
// Spring Boot gh-7270
132+
return new BrokenFactoryBean();
133+
}
134+
135+
@Bean
136+
WorkingFactoryBean singletonFactoryBean() {
137+
return new WorkingFactoryBean();
138+
}
139+
140+
@Bean
141+
NonSingletonFactoryBean nonSingletonFactoryBean() {
142+
return new NonSingletonFactoryBean();
143+
}
144+
145+
}
146+
147+
static class BrokenFactoryBean implements FactoryBean<String> {
148+
149+
@Override
150+
public String getObject() {
151+
throw new IllegalStateException();
152+
}
153+
154+
@Override
155+
public Class<?> getObjectType() {
156+
return String.class;
157+
}
158+
159+
@Override
160+
public boolean isSingleton() {
161+
return true;
162+
}
163+
164+
}
165+
166+
static class WorkingFactoryBean implements FactoryBean<ExampleService> {
167+
168+
private final ExampleService service = mock(ExampleService.class, MockReset.before());
169+
170+
@Override
171+
public ExampleService getObject() {
172+
return this.service;
173+
}
174+
175+
@Override
176+
public Class<?> getObjectType() {
177+
return ExampleService.class;
178+
}
179+
180+
@Override
181+
public boolean isSingleton() {
182+
return true;
183+
}
184+
185+
}
186+
187+
static class NonSingletonFactoryBean implements FactoryBean<ExampleService> {
188+
189+
private int getObjectInvocations = 0;
190+
191+
@Override
192+
public ExampleService getObject() {
193+
this.getObjectInvocations++;
194+
return mock(ExampleService.class, MockReset.before());
195+
}
196+
197+
@Override
198+
public Class<?> getObjectType() {
199+
return ExampleService.class;
200+
}
201+
202+
@Override
203+
public boolean isSingleton() {
204+
return false;
205+
}
206+
207+
}
208+
209+
}

0 commit comments

Comments
 (0)