jack
jack

Reputation: 833

SpringBoot disabling DataSourceAutoconfigure error while running Junit Tests

I have Springboot application works fine which connects to the Datasource. For Junit I have disabled the Autoconfigure of DataSource by excluding the DatasourceAutoConfiguration, DataSourceTransactionManagerConfiguration, HibernateJpaAutoConfiguration classes to avoid SpringBoot Autoconfiguring the DataSource.

pom.xml

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
<dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
  <version>2.2.5.RELEASE</version>
<dependency>
<dependency>
  <groupId>com.microsoft.sqlserver</groupId>
  <artifactId>mssql-jdbc</artifactId>
  <version>8.2.2.jre8</version>
<dependency>

Main class

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan({"com.basepackage"})
public class SampleClass{
  psvm(){
  SpringApplication.run(SampleClass.class,args);
}
}

JuniTestClass

@RunWith(SpringRunner.class)
@SpringBootTest(classes=SampleClass.class)
@AutoConfigureMockMvc
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class, DataSourceTransactionManagerConfiguration.class, HibernateJpaAutoConfiguration.class})
public class SampleControllerTest {
  @MockBean
  private SampleService service;

  @Test
  public void fetchUsers() {
    Mockito.when(service.retrieveUsers().thenReturn(new SampleResponse());
}

}

On mvn test, the Test scripts are run but failing, because SampleRepository bean is not Autoconfigured (might be because of exclusion of the Datasource and HibernateJpa autoconfig classes) by Springboot

Error

Caused by UnsatisfiedDependencyException: Error creating bean with name ServiceDAOImpl, nested exception No qualifying bean of type com.basepackage.repository.SampleRepository' : expected atleast 1 bean which qualifies ...................

If I remove the AutoConfig Exclusion, the Junit tests works fine in local workspace which configures Datasource (though with JUnit connectivity to DB should not be established). The issue is I am setting up devops pipeline and during "Maven Test", SpringBoot autoconfigures the DataSource and the connectivity to Jenkins to DB fails.

I would like to disable the Autoconfig during Junit - Maven Test and on actual SpringBoot jar build, the autoconfiguration should be enabled.

Can someone please let me know how to achieve this with Annotations?

Upvotes: 2

Views: 3473

Answers (1)

rieckpil
rieckpil

Reputation: 12041

Disabling auto-configuration for your database is one thing, but your application classes rely on (I guess) JPA repositories from Spring Data (they inject it using @Autowired) to work.

If you now disable auto-configuration for your database, your JPA repositories can't be bootstrapped by Spring Data and hence your service classes fail on startup as they require an available instance: ... expected at least 1 bean which qualifies.

I guess you have three choices to solve this:

  1. Use Testcontainers to provide a real database during your tests and enable auto-configuration of the data related parts again. This would be the best solution as you can test your application with the same database you use in production.
  2. Keep disabling auto-configuration, but provide a manual datasource configuration for your tests:
@SpringBootTest
class ApplicationIntegrationTest {

  @TestConfiguration
  public static class TestConfig {

    @Bean
    public DataSource dataSource() {
      return DataSourceBuilder
        .create()
        .password("YOUR PASSWORD")
        .url("YOUR MSSQL URL")
        .username("YOUR USERNAME")
        .build();
    }
  }
}
  1. Use @MockBean for all your repositories. This would allow you to completetly work without any database, but you would have to define any interaction with your repositories for yourself using Mockito:
@SpringBootTest
class SpringBootStackoverflowApplicationTests {

  @MockBean
  private SampleRepository sampleRepository;
  
  @MockBean
  private OtherRepository otherRepository;
  
  // your tests
}

Upvotes: 6

Related Questions