运行 测试 Spring 引导在上下文中失败
Running tests in Spring Boot fails in context
我正在编写 Spring Boot (1.5.7) REST 应用程序,它运行良好,没有问题。
现在我正在尝试编写一些 unit/integration 测试,但我不知道如何配置它们。
这是我的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();
}
}
这是我的测试之一,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());
}
}
所有测试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)}"
这是应用的配置文件-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
我会调查 Mockito。我发现它对于单元测试 spring 启动应用程序非常有用。
你最终会得到类似的东西。
public class NetworkServiceTest
{
@Mock
private TestEntityManager manager;
@Mock
private NetworkService service;
....
}
您已使用 @DataJpaTest
对测试 class 进行了注释,但您似乎在测试服务层(因为您正在尝试自动装配 NetworkService),而不是 JPA 层。
尝试删除 @DataJpaTest
注释。
根据@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);
}
}
我正在编写 Spring Boot (1.5.7) REST 应用程序,它运行良好,没有问题。
现在我正在尝试编写一些 unit/integration 测试,但我不知道如何配置它们。
这是我的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();
}
}
这是我的测试之一,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());
}
}
所有测试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)}"
这是应用的配置文件-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
我会调查 Mockito。我发现它对于单元测试 spring 启动应用程序非常有用。
你最终会得到类似的东西。
public class NetworkServiceTest
{
@Mock
private TestEntityManager manager;
@Mock
private NetworkService service;
....
}
您已使用 @DataJpaTest
对测试 class 进行了注释,但您似乎在测试服务层(因为您正在尝试自动装配 NetworkService),而不是 JPA 层。
尝试删除 @DataJpaTest
注释。
根据@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);
}
}