我将应用程序从JDBC / REST移植到spring-data-rest
并且我的唯一单元测试失败并显示错误
NoSuchBeanDefinitionException:
No qualifying bean of type 'com.xxx.repository.ForecastRepository' available
该应用程序之前刚刚使用spring-boot
进行了改编,现在我尝试在spring-data-rest
之上添加spring-data-jpa
新图层。
我试图根据
计算出正确的Java配置Custom Test Slice with Spring Boot 1.4
但我不得不偏离惯用法,因为
@WebMvcTest
注释没有抑制导致测试失败的安全模块@MockMvcAutoConfiguration
由于缺少依赖项而失败,除非我指定@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
(请参阅here)@WebMvcTest
和@SpringBootTest
是互斥的,因为它们都指定了@BootstrapWith
并且无法一起运行所以这是我最接近的,但Spring无法找到我的@RepositoryRestResource
存储库:
存储库
@RepositoryRestResource(collectionResourceRel = "forecasts", path = "forecasts")
public interface ForecastRepository extends CrudRepository<ForecastExEncoded,
Long> {
JUnit测试
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK,
classes = {TestRestConfiguration.class})
public class ForecastRestTests {
@Autowired
private MockMvc mockMvc;
@Autowired
private ForecastRepository forecastRepository;
@Before
public void deleteAllBeforeTests() throws Exception {
forecastRepository.deleteAll();
}
@Test
public void shouldReturnRepositoryIndex() throws Exception {
mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk()).andExpect(
jsonPath("$._links.forecasts").exists());
}
}
配置
@OverrideAutoConfiguration(enabled = false)
@ImportAutoConfiguration(value = {
RepositoryRestMvcAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
WebMvcAutoConfiguration.class,
MockMvcAutoConfiguration.class,
MockMvcSecurityAutoConfiguration.class
})
@Import({PropertySpringConfig.class})
public class TestRestConfiguration {}
还试过......
我尝试仅使用@WebMvcTest
以及How to exclude AutoConfiguration from Spring Boot下面的@ComponentScan
来配置单元测试,以试图简化所有内容,但是excludeFilters
没有效果。
@ComponentScan(
basePackages="com.xxx",
excludeFilters = {
@ComponentScan.Filter(type = ASSIGNABLE_TYPE,
value = {
SpringBootWebApplication.class,
JpaDataConfiguration.class,
SecurityConfig.class
})
})
我已将Spring的日志记录设置为跟踪,因为此时我所能做的就是尝试找到有关日志输出发生情况的线索。到目前为止虽然没有运气。
我可以在日志记录中看到RepositoryRestConfiguration正在加载,但显然它没有提供正确的信息,我无法弄清楚如何完成这项工作,谷歌搜索和倾注春天docs和API。我想我必须在这里阅读所有相关问题。
更新2016-11-16 10:00
我在日志中看到的有关我的一件事是:
Performing dependency injection for test context [DefaultTestContext@2b4a2ec7 [snip...]
classes = '{class com.xxx.TestRestConfiguration,
class com.xxx.TestRestConfiguration}',
即。上下文列出配置类 两次 。我在@SpringBootTest#classes
注释上指定了配置类(仅一次)。但是如果我从注释中省略#classes
,Spring Boot会通过@SpringBootApplication
类找到并拉入所有配置。
那是一个提示我在错误的地方指定配置吗?我怎么办呢?
答案 0 :(得分:1)
经过太多时间,我决定采用这种方法。
Custom Test Slice with Spring Boot 1.4看起来很有希望,但我无法随心所欲。
一遍又一遍
我意识到我必须包含JPA设置,因为spring-data-rest
直接使用它们 - 没有机会模拟它们或没有嵌入式数据库运行单元测试。
至少不是我理解的。也许有可能模仿它们并让spring-data-rest
针对测试数据运行模拟,但我认为spring-data-rest
和spring-data
可能过于紧密耦合。
因此必须进行集成测试。
在随上述文章提供的Spring源代码中
gs-accessing-data-rest/ApplicationTests.java
日志记录显示Spring Boot引入了应用程序上下文的整个配置。
为了避免我的SpringBootApplication
类并且没有加载安全模块,我设置了这样的测试:
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = {
JpaDataConfiguration.class,
TestJpaConfiguration.class,
TestRestConfiguration.class,
PropertySpringConfig.class})
public class ForecastRestTests {
@SuppressWarnings("SpringJavaAutowiringInspection")
@Autowired
private MockMvc mockMvc;
@Autowired
private ForecastRepository forecastRepository;
@Before
public void deleteAllBeforeTests() throws Exception {
forecastRepository.deleteAll();
}
@Test
public void shouldReturnRepositoryIndex() throws Exception {
mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk()).andExpect(
jsonPath("$._links.forecasts").exists());
}
}
使用这些配置类:
@Configuration
@EnableJpaRepositories(basePackages = {"com.bp.gis.tardis.repository"})
@EntityScan(basePackages = {"com.bp.gis.tardis.type"})
public class JpaDataConfiguration {
和
@Configuration
@OverrideAutoConfiguration(enabled = false)
@ImportAutoConfiguration(value = {
CacheAutoConfiguration.class,
JpaRepositoriesAutoConfiguration.class,
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
TransactionAutoConfiguration.class,
TestDatabaseAutoConfiguration.class,
TestEntityManagerAutoConfiguration.class })
public class TestJpaConfiguration {}
和
@Configuration
@OverrideAutoConfiguration(enabled = false)
@ImportAutoConfiguration(value = {
RepositoryRestMvcAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
WebMvcAutoConfiguration.class,
MockMvcAutoConfiguration.class,
MockMvcSecurityAutoConfiguration.class
})
public class TestRestConfiguration {}
所以TL; DR摘要是:使用@ContextConfiguration
指定指定@OverrideAutoConfiguration
和@ImportAutoConfiguration