Junit cannot detect an @Autowired Bean during a test of a configuration class in Java

Viewed 1048

I have a configuration class like the following

@Configuration
public class Configuration {

  @Autowired
  private JdbcTemplate jdbcTemplate;

  @Bean
  SimpleJdbcCall simpleJdbcCall() {
    return new SimpleJdbcCall(jdbcTemplate).withProcedureName("");
  }

}

I am trying to write a unit test for this configuration class. My test class looks like the following.

@ContextConfiguration(classes = { Configuration.class })
@RunWith(SpringRunner.class)
public class ConfigurationTest {

  ApplicationContextRunner context = new ApplicationContextRunner()
                                         .withUserConfiguration(Configuration.class);

  @Test
  public void should_check_presence_of_example_service() {
    context.run(it -> {
      assertThat(it).hasSingleBean(SimpleJdbcCall.class);
    });
  }
}

When I am running the test in the ConfigurationTest class, I am getting an error like the one below.

Error creating bean with name 'Configuration': Unsatisfied dependency expressed through field 'jdbcTemplate'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.jdbc.core.JdbcTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

I tried to solve this by crating a bean jdbcTemplate in the Configuration class and passed datasource. Then the test unit test does not find the bean datasource. After that I used @TestConfiguration in the ConfigurationTest class and crated a mock(jdbcTemplate). That did not work either.

1 Answers

I found a solution for my problem, and I thought it might be helpful for others if someone is in the same situation. Actually my goal was to increase the test coverage because of the company requirement, and the following solution works for me.

I changed my configuration class like below

@Configuration
public class Configuration {

  @Bean
  SimpleJdbcCall simpleJdbcCall(DataSource dataSource) {
    return new SimpleJdbcCall(dataSource).withProcedureName("");
  }

} 

I had to change my test class like below. Now the test class is not complaining, and I am getting 100% coverage of the Configuration class.

@SpringBootTest
public class ConfigurationTest {

  @TestConfiguration
  static class MyConfiguration {
    @Bean
    DataSource dataSource() {
      return mock(DataSource.class);
    }
  }

  @Autowired
  private DataSource dataSource;

  @Autowired
  private Configuration configuration;

  @Test
  public void should_check_presence_of_simpleJdbcCall_Bean() {
    SimpleJdbcCall simpleJdbcCall = configuration.simpleJdbcCall(dataSource);
    Assertions.assertNotNull(simpleJdbcCall);
  }

}
Related