Stubbing methods of injected beans in another bean’s constructors

I test a Spring bean using constructor injection. The injected bean is defined as @MockBean in the testcase and also the appropriate stub is defined: when a certain method of the mocked bean is called, then it should return a mocked object.

When I start the testcase I get a NullPointerException, because the stubbing does not work – the method returns always null.

Here is the constructor of the object to test:

@Autowired
public MyBeanToTest(msTemplate jmsTemplate) throws JMSException {
    this.jmsTemplate = jmsTemplate;
    this.cf = this.jmsTemplate.getConnectionFactory(); // cf is always null
    cf.createSession(); // NPE
}

Here is the testcase:

@SpringBootTest
public class MyTestClass {
    @Autowired
    MyBeanToTest myBeanToTest;

    @MockBean
    private JmsTemplate jmsTemplate;
    
    @Mock
    private static ConnectionFactory connectionFactory;

    @Test
    public void testSomething()  {
        ...
        when( jmsTemplate.getConnectionFactory() ).thenReturn( connectionFactory );
        ...
    }
}

I assume the defined stubbing is not active yet when the constructor is called. Any idea how can I make it work?

Answer

Your assumption is correct. Your best bet is to create the bean ‘by hand’ instead of letting Spring call the constructor all by itself. To this end, add a @Configuration class to your test that has the corresponping @Bean method.


Untested example:

@SpringBootTest
public class MyTestClass {

    @Configuration
    static class MyTestClassConfiguration {
        @Bean
        MyBeanToTest myBeanToTest(jmsTemplate jmsTemplate) {
            // Too bad that this is not within the test…
            when(jmsTemplate.getConnectionFactory())
                    .thenReturn(connectionFactory);
            …
        }
    }
    
}