Skip to content

Commit 107ae61

Browse files
committed
Add tests for MockitoBean reset of mocks/spies from a FactoryBean
Closes gh-33405
1 parent 94d8fc7 commit 107ae61

File tree

4 files changed

+259
-2
lines changed

4 files changed

+259
-2
lines changed

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.concurrent.atomic.AtomicBoolean;
2020

21+
import org.junit.jupiter.api.Order;
2122
import org.junit.jupiter.api.Test;
2223

2324
import org.springframework.beans.factory.FactoryBean;
@@ -44,17 +45,24 @@ class MockitoBeanForBeanFactoryIntegrationTests {
4445
@Autowired
4546
private ApplicationContext applicationContext;
4647

48+
@Order(1)
4749
@Test
4850
void beanReturnedByFactoryIsMocked() {
4951
TestBean bean = this.applicationContext.getBean(TestBean.class);
5052
assertThat(bean).isSameAs(this.testBean);
5153

52-
when(testBean.hello()).thenReturn("amock");
54+
when(this.testBean.hello()).thenReturn("amock");
5355
assertThat(bean.hello()).isEqualTo("amock");
5456

5557
assertThat(TestFactoryBean.USED).isFalse();
5658
}
5759

60+
@Order(2)
61+
@Test
62+
void beanReturnedByFactoryIsReset() {
63+
assertThat(this.testBean.hello()).isNull();
64+
}
65+
5866
@Configuration(proxyBeanMethods = false)
5967
static class Config {
6068

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright 2002-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.Order;
20+
import org.junit.jupiter.api.Test;
21+
22+
import org.springframework.beans.factory.FactoryBean;
23+
import org.springframework.beans.factory.annotation.Qualifier;
24+
import org.springframework.context.ApplicationContext;
25+
import org.springframework.context.annotation.Bean;
26+
import org.springframework.context.annotation.Configuration;
27+
import org.springframework.lang.Nullable;
28+
import org.springframework.test.context.bean.override.example.ExampleService;
29+
import org.springframework.test.context.bean.override.example.FailingExampleService;
30+
import org.springframework.test.context.bean.override.example.RealExampleService;
31+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
32+
33+
import static org.assertj.core.api.Assertions.assertThat;
34+
import static org.mockito.Mockito.doReturn;
35+
36+
/**
37+
* Integration tests for {@link MockitoBean} that validate automatic reset
38+
* of stubbing.
39+
*
40+
* @author Simon Baslé
41+
* @since 6.2
42+
*/
43+
@SpringJUnitConfig
44+
public class MockitoBeanWithResetIntegrationTests {
45+
46+
@MockitoBean(reset = MockReset.BEFORE)
47+
ExampleService service;
48+
49+
@MockitoBean(reset = MockReset.BEFORE)
50+
FailingExampleService failingService;
51+
52+
@Order(1)
53+
@Test
54+
void beanFirstEstablishingMock(ApplicationContext ctx) {
55+
ExampleService mock = ctx.getBean("service", ExampleService.class);
56+
doReturn("Mocked hello").when(mock).greeting();
57+
58+
assertThat(this.service.greeting()).isEqualTo("Mocked hello");
59+
}
60+
61+
@Order(2)
62+
@Test
63+
void beanSecondEnsuringMockReset(ApplicationContext ctx) {
64+
assertThat(ctx.getBean("service")).isNotNull().isSameAs(this.service);
65+
66+
assertThat(this.service.greeting()).as("not stubbed").isNull();
67+
}
68+
69+
@Order(3)
70+
@Test
71+
void factoryBeanFirstEstablishingMock(ApplicationContext ctx) {
72+
FailingExampleService mock = ctx.getBean(FailingExampleService.class);
73+
doReturn("Mocked hello").when(mock).greeting();
74+
75+
assertThat(this.failingService.greeting()).isEqualTo("Mocked hello");
76+
}
77+
78+
@Order(4)
79+
@Test
80+
void factoryBeanSecondEnsuringMockReset(ApplicationContext ctx) {
81+
assertThat(ctx.getBean("factory")).isNotNull().isSameAs(this.failingService);
82+
83+
assertThat(this.failingService.greeting()).as("not stubbed")
84+
.isNull();
85+
}
86+
87+
static class FailingExampleServiceFactory implements FactoryBean<FailingExampleService> {
88+
@Nullable
89+
@Override
90+
public FailingExampleService getObject() {
91+
return new FailingExampleService();
92+
}
93+
94+
@Nullable
95+
@Override
96+
public Class<?> getObjectType() {
97+
return FailingExampleService.class;
98+
}
99+
}
100+
101+
@Configuration
102+
static class Config {
103+
104+
@Bean("service")
105+
ExampleService bean1() {
106+
return new RealExampleService("Production hello");
107+
}
108+
109+
@Bean("factory")
110+
@Qualifier("factory")
111+
FailingExampleServiceFactory factory() {
112+
return new FailingExampleServiceFactory();
113+
}
114+
}
115+
116+
}

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.test.context.bean.override.mockito;
1818

19+
import org.junit.jupiter.api.Order;
1920
import org.junit.jupiter.api.Test;
2021
import org.mockito.Mockito;
2122

@@ -28,6 +29,7 @@
2829
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
2930

3031
import static org.assertj.core.api.Assertions.assertThat;
32+
import static org.mockito.Mockito.doReturn;
3133

3234
/**
3335
* Test {@link MockitoSpyBean @MockitoSpyBean} for a factory bean configuration.
@@ -46,13 +48,25 @@ class MockitoSpyBeanForBeanFactoryIntegrationTests {
4648
@Autowired
4749
private ApplicationContext applicationContext;
4850

51+
@Order(1)
4952
@Test
5053
void beanReturnedByFactoryIsSpied() {
5154
TestBean bean = this.applicationContext.getBean(TestBean.class);
5255
assertThat(this.testBean).as("injected same").isSameAs(bean);
5356
assertThat(bean.hello()).isEqualTo("hi");
54-
5557
Mockito.verify(bean).hello();
58+
59+
doReturn("sp-hi").when(this.testBean).hello();
60+
61+
assertThat(bean.hello()).as("after stubbing").isEqualTo("sp-hi");
62+
Mockito.verify(bean, Mockito.times(2)).hello();
63+
}
64+
65+
@Order(2)
66+
@Test
67+
void beanReturnedByFactoryIsReset() {
68+
assertThat(this.testBean.hello())
69+
.isNotEqualTo("sp-hi");
5670
}
5771

5872
@Test
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright 2002-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.Order;
20+
import org.junit.jupiter.api.Test;
21+
22+
import org.springframework.beans.factory.FactoryBean;
23+
import org.springframework.beans.factory.annotation.Qualifier;
24+
import org.springframework.context.ApplicationContext;
25+
import org.springframework.context.annotation.Bean;
26+
import org.springframework.context.annotation.Configuration;
27+
import org.springframework.lang.Nullable;
28+
import org.springframework.test.context.bean.override.example.ExampleService;
29+
import org.springframework.test.context.bean.override.example.FailingExampleService;
30+
import org.springframework.test.context.bean.override.example.RealExampleService;
31+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
32+
33+
import static org.assertj.core.api.Assertions.assertThat;
34+
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
35+
import static org.mockito.Mockito.doReturn;
36+
37+
/**
38+
* Integration tests for {@link MockitoSpyBean} that validate automatic reset
39+
* of stubbing.
40+
*
41+
* @author Simon Baslé
42+
* @since 6.2
43+
*/
44+
@SpringJUnitConfig
45+
public class MockitoSpyBeanWithResetIntegrationTests {
46+
47+
@MockitoSpyBean(reset = MockReset.BEFORE)
48+
ExampleService service;
49+
50+
@MockitoSpyBean(reset = MockReset.BEFORE)
51+
FailingExampleService failingService;
52+
53+
@Order(1)
54+
@Test
55+
void beanFirstEstablishingStub(ApplicationContext ctx) {
56+
ExampleService spy = ctx.getBean("service", ExampleService.class);
57+
doReturn("Stubbed hello").when(spy).greeting();
58+
59+
assertThat(this.service.greeting()).isEqualTo("Stubbed hello");
60+
}
61+
62+
@Order(2)
63+
@Test
64+
void beanSecondEnsuringStubReset(ApplicationContext ctx) {
65+
assertThat(ctx.getBean("service")).isNotNull().isSameAs(this.service);
66+
67+
assertThat(this.service.greeting()).as("not stubbed")
68+
.isEqualTo("Production hello");
69+
}
70+
71+
@Order(3)
72+
@Test
73+
void factoryBeanFirstEstablishingStub(ApplicationContext ctx) {
74+
FailingExampleService spy = ctx.getBean(FailingExampleService.class);
75+
doReturn("Stubbed hello").when(spy).greeting();
76+
77+
assertThat(this.failingService.greeting()).isEqualTo("Stubbed hello");
78+
}
79+
80+
@Order(4)
81+
@Test
82+
void factoryBeanSecondEnsuringStubReset(ApplicationContext ctx) {
83+
assertThat(ctx.getBean("factory")).isNotNull().isSameAs(this.failingService);
84+
85+
assertThatIllegalStateException().isThrownBy(this.failingService::greeting)
86+
.as("not stubbed")
87+
.withMessage("Failed");
88+
}
89+
90+
static class FailingExampleServiceFactory implements FactoryBean<FailingExampleService> {
91+
@Nullable
92+
@Override
93+
public FailingExampleService getObject() {
94+
return new FailingExampleService();
95+
}
96+
97+
@Nullable
98+
@Override
99+
public Class<?> getObjectType() {
100+
return FailingExampleService.class;
101+
}
102+
}
103+
104+
@Configuration
105+
static class Config {
106+
107+
@Bean("service")
108+
ExampleService bean1() {
109+
return new RealExampleService("Production hello");
110+
}
111+
112+
@Bean("factory")
113+
@Qualifier("factory")
114+
FailingExampleServiceFactory factory() {
115+
return new FailingExampleServiceFactory();
116+
}
117+
}
118+
119+
}

0 commit comments

Comments
 (0)