- 
                Notifications
    You must be signed in to change notification settings 
- Fork 41.6k
Closed
Description
@MockBean document states
Any existing single bean of the same type defined in the context will be replaced by the mock.
However, it also replaces the bean for a sub-type. I suspect it's because the following line as ListableBeanFactory#getBeanNamesForType also includes subclasses.
Lines 250 to 251 in 303dd4c
| private Set<String> getExistingBeans(ConfigurableListableBeanFactory beanFactory, ResolvableType type) { | |
| Set<String> beans = new LinkedHashSet<>(Arrays.asList(beanFactory.getBeanNamesForType(type, true, false))); | 
I've updated MockBeanOnTestClassForExistingBeanIntegrationTests to demonstrate what I expected, where FailingExampleService is a subclass of ExampleService (Please ignore potential wiring issues):
@ExtendWith(SpringExtension.class)
@MockBean(ExampleService.class)
class MockBeanOnTestClassForExistingBeanIntegrationTests {
	@Autowired
	private ApplicationContext applicationContext;
	@Autowired
	private ExampleServiceCaller caller;
	@Test
	void testMocking() {
		given(this.caller.getService().greeting()).willReturn("Boot");
		assertThat(this.caller.sayGreeting()).isEqualTo("I say Boot");
	}
	@Test
	void testBeans() {
		assertThat(applicationContext.getBeanNamesForType(ExampleService.class)).hasSize(2);
		assertThat(applicationContext.getBeanNamesForType(FailingExampleService.class)).hasSize(1);
	}
	@Configuration(proxyBeanMethods = false)
	@Import({ ExampleServiceCaller.class, FailingExampleService.class })
	static class Config {
	}
}Spring Boot version: 2.5.5
rickie
Metadata
Metadata
Assignees
Labels
type: documentationA documentation updateA documentation update