Environment: Spring 6.2.0-M1, Java 21

Example project: https://github.com/hantsy/spring6-sandbox/tree/master/test-bean

I tried to write a test to experience the new @MockitoSpyBean.

@SpringJUnitConfig(classes = Config.class)
class CustomerServiceMockitoSpyTest {

    @MockitoSpyBean
    CustomerService customerService;

    @Test
    public void testCustomerService() {
        when(customerService.findByEmail("dummy@example.com"))
                .thenReturn(
                        new Customer("dummy first", "dummy last", "dummy@example.com")
                );

        // test bean
        var testCustomer = customerService.findByEmail("dummy@example.com");
        assertThat(testCustomer.firstName()).isEqualTo("dummy first");
        assertThat(testCustomer.lastName()).isEqualTo("dummy last");
        assertThat(customerService.findAll().size()).isEqualTo(2);

        verify(customerService, times(1)).findByEmail(anyString());
        verify(customerService, times(1)).findAll();
        verifyNoMoreInteractions(customerService);
    }
}

I tried to use customerServiceSpy as the field name here, but it does not work. I have to use customerSerivce here and set the bean name attribute.

Whereas, in the test that's testing @MockitoBean in CustomerServiceMockitoTest, using customerServiceMock(no need set the bean name) worked well.

The spied field name should be named by developers freely, and the spied bean should override the real bean by type (not name) firstly.

Comment From: snicoll

See also #32760.

It looks like bean overriding does not work with a by-type semantic. While that's a choice we can make, it looks like the Mockito support in Spring Boot does do that. If I haven't overlooked anything, this seems to me a too intrusive change of behavior for people moving from the Spring Boot support, so we should support that as well IMO.

Comment From: hantsy

This is for @MockitoSpyBean. They are handled in the different override processors.

If you think they are the same issue, close https://github.com/spring-projects/spring-framework/issues/32760.

Comment From: aditya78910

See also #32760.

It looks like bean overriding does not work with a by-type semantic. While that's a choice we can make, it looks like the Mockito support in Spring Boot does do that. If I haven't overlooked anything, this seems to me a too intrusive change of behavior for people moving from the Spring Boot support.

Hi @snicoll

are you referring to MockBean and SpyBean from Spring Boot. Both of these seem to override beans by-type.

If this true, can you please explain a bit more about how making the same change here is intrusive?

Comment From: snicoll

I am saying the exact opposite. Having by-type support in Spring Boot and not here is a too intrusive change of behavior.

Comment From: simonbasle

Note that in the second case (CustomerServiceMockitoTest) it appears to work because a new bean named customerServiceMock is created (per bean overriding CREATE_OR_REPLACE strategy). So the context now contains two beans of type CustomerService: the prod one and the mock one.

I've started making modifications to override based on type by default, but I need to clarify what should happen in the case where multiple candidates are found when looking up that way.

Comment From: snicoll

I need to clarify what should happen in the case where multiple candidates are found when looking up that way.

I am wondering why we wouldn’t consider what Spring Boot does for a start. The algorithm looks straightforward enough to me, with the addition of the qualifier in the metadata.

Comment From: simonbasle

@TestBean, @MockitoBean and @MockitoSpyBean now match a bean by type if no explicit bean name is provided. I would nonetheless encourage users to be as explicit as possible (i.e. specify a bean name) when overriding beans.

I will follow up in another issue for M3 (#32822) to introduce the option of also using qualifiers.