I'm porting an app across from JDBC / REST to spring-data-rest
and my one and only unit test with fails with the error
NoSuchBeanDefinitionException:
No qualifying bean of type 'com.xxx.repository.ForecastRepository' available
The app was retro-fitted with spring-boot
just previously, and now I'm trying to put a new layer in place with spring-data-rest
on top of spring-data-jpa
.
I'm attempting to work out the correct Java-config according to
Custom Test Slice with Spring Boot 1.4
but I had to deviate from the idiomatic approach because
- the
@WebMvcTest
annotation doesn't suppress the security module which causes the test to fail - the
@MockMvcAutoConfiguration
fails due to missing dependencies unless I specify@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
(see here) @WebMvcTest
and@SpringBootTest
are mutually exclusive since they both specify@BootstrapWith
and can't run together
So this is the closest I've got but Spring can't locate my @RepositoryRestResource
repository:
Repository
@RepositoryRestResource(collectionResourceRel = "forecasts", path = "forecasts")
public interface ForecastRepository extends CrudRepository<ForecastExEncoded,
Long> {
JUnit Test
@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());
}
}
Configuration
@OverrideAutoConfiguration(enabled = false)
@ImportAutoConfiguration(value = {
RepositoryRestMvcAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
WebMvcAutoConfiguration.class,
MockMvcAutoConfiguration.class,
MockMvcSecurityAutoConfiguration.class
})
@Import({PropertySpringConfig.class})
public class TestRestConfiguration {}
Also tried...
I tried to configure the unit test with just @WebMvcTest
and this @ComponentScan
below from How to exclude AutoConfiguration from Spring Boot), in an attempt to simplify it all, however the excludeFilters
had no effect.
@ComponentScan(
basePackages="com.xxx",
excludeFilters = {
@ComponentScan.Filter(type = ASSIGNABLE_TYPE,
value = {
SpringBootWebApplication.class,
JpaDataConfiguration.class,
SecurityConfig.class
})
})
I've set Spring's logging to trace because all I can do at this point is try to find clues as to what is happening from log output. So far though without any luck.
I can see in the logging that RepositoryRestConfiguration is loading, but obviously it isn't fed with the right info and I am unable to work out how that is done, after googling and pouring over the Spring docs and API. I think I must have read every relevant question here on SO .
Update 2016-11-16 10:00
One thing I see in the logs which concerns me is this:
Performing dependency injection for test context [DefaultTestContext@2b4a2ec7 [snip...]
classes = '{class com.xxx.TestRestConfiguration,
class com.xxx.TestRestConfiguration}',
i.e. the context lists the configuration class twice. I specified the config class (once only) on the @SpringBootTest#classes
annotation. But if I leave off the #classes
from the annotation, Spring Boot finds and pulls in all the config via the @SpringBootApplication
class.
So is that a hint that I am specifying the configuration in the wrong place? How else would I do it?