Running tests in Spring Boot fails in context

Viewed 8794

I'm writing a Spring Boot (1.5.7) REST application, which is working nice without problems.

Now I'm trying to write some unit/integration tests but I can't figure how to configure them.

This is my Application.java

@EntityScan
@SpringBootApplication
public class Application
{
    public static void main(String[] args)
    {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public Module hibernate5Module()
    {
        return new Hibernate5Module();
    }
}

This is one of my test, NetworkServiceTest.java

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@ActiveProfiles(profiles = "test")
@DataJpaTest
public class NetworkServiceTest
{
    @Autowired
    private TestEntityManager manager;
    @Autowired
    private NetworkService service;

    @Test
    public void whenFindByFacilityIdAndSportId_thenReturnNetwork()
    {
        // Given
        Network net = new Network(100, 200);
        manager.persist(net);
        manager.flush();

        // When
        Network found = service.findByFacilityIdAndSportId(net.getFacilityId(), net.getSportId());

        // Then
        assertThat(found.getFacilityId()).isEqualTo(net.getFacilityId());
        assertThat(found.getSportId()).isEqualTo(net.getSportId());
    }
}

All tests return "NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.NetworkService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}"

This is the configuration file application-test.yml

spring:
    datasource:
        url: jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE
        username: sa
        password: 
        driver-class-name: org.h2.Driver
    jpa:
        hibernate:
            ddl-auto: create
liquibase:
    enabled: false
3 Answers

Resolved following hints from @darren-forsythe

BaseTest.java

@RunWith(SpringRunner.class)
@ActiveProfiles(profiles = "test")
abstract class BaseTest
{
    @Test
    public void init() {}
}

BaseDatabaseTest.java

@DataJpaTest
@ComponentScan(basePackages = { "com.example.services"})
abstract class BaseDatabaseTest extends BaseTest
{
    @Autowired
    protected TestEntityManager m_pManager;

    @Test
    public void initDatabase() {}
}

NetworkServiceTest.java

public class NetworkServiceTest extends BaseDatabaseTest
{
    @Autowired
    private NetworkService service;

    @Test
    public void whenFindByFacilityIdAndSportId_thenReturnNetwork()
    {
        long facilityId = 100;
        long sportId = 200;

        // Given
        Network net = new Network(facilityId, sportId);
        m_pManager.persist(net);
        m_pManager.flush();

        assertThat(net.getFacilityId()).isEqualTo(facilityId);

        // When
        List<Network> nets = service.findAll();
        Network found = service.findByFacilityIdAndSportId(facilityId, sportId);

        // Then
        assertThat(nets.size()).isGreaterThan(0);
        assertThat(found.getFacilityId()).isEqualTo(net.getFacilityId());
        assertThat(found.getSportId()).isEqualTo(net.getSportId());
        assertThat(found.getSportId()).isNotEqualTo(0);
    }
}

You have annotated the test class with @DataJpaTest but you seem to be testing the service layer (since you are trying to autowire NetworkService), not the JPA layer.

try removing the @DataJpaTest annotation.

I would look into Mockito. I've found it to be extremely useful for unit testing spring boot applications.

You'll end up having something like.

public class NetworkServiceTest
{
    @Mock
    private TestEntityManager manager;
    @Mock
    private NetworkService service;

    ....
}
Related