I was trying to play a little bit with integration test in springboot, hence I build some sample test using @SpringBootTest
annotation. My sample test is :
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = IntegrationTestConfig.class)
public class WeatherForCityIT {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void getWeatherForExistingCity() throws Exception {
String existingCity = "London";
ResponseEntity<String> responseEntity = restTemplate.getForEntity("/weather/{cityName}",String.class,existingCity.toString());
Assertions.assertThat(responseEntity).isNotNull();
}
}
And have following controller class
@RestController
@RequestMapping("/weather")
public class ChartController {
private WeatherForecastAPI weatherForecastAPI;
@Autowired
public void setWeatherForecastAPI(WeatherForecastAPI weatherForecastAPI) {
this.weatherForecastAPI = weatherForecastAPI;
}
@GetMapping("/{cityName}")
public List<WeatherForecastDTO> get5daysForecast(@PathVariable String cityName) {
weatherForecastAPI.getWeatherForecastByCity(cityWithCountryCode.toString());
}
}
Unfortunately in response body I get message 404 Not Found. In debug mode I see that it never reaches defined controller. Am I missing something from configuration perspective ? I was trying to also use MockMvc :
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@ContextConfiguration(classes = IntegrationTestConfig.class)
public class WeatherForCityIT {
@Autowired
private MockMvc mockMvc;
@Test
public void getWeatherForExistingCity() throws Exception {
String existingCity = "London";
restTemplate.getForEntity("/weather/{cityName}",String.class,existingCity);
mockMvc.perform(get("/weather/" + existingCity))
.andDo(print())
.andExpect(MockMvcResultMatchers.status().isOk());
}
}
but also without success (again 404 instead of 202).
EDITED
Configuration class looks following:
@Configuration
@EnableAutoConfiguration
public class IntegrationTestConfig {
@Bean
public com.jayway.jsonpath.Configuration configuration() {
return com.jayway.jsonpath.Configuration.builder()
.jsonProvider(new JacksonJsonProvider())
.mappingProvider(new JacksonMappingProvider())
.options(EnumSet.noneOf(Option.class))
.build();
}
}
You do not need @EnableAutoConfiguration
in your test configuration class. Therefore IntegrationTestConfig should look like:
@TestConfiguration
public class IntegrationTestConfig {
@Bean
public com.jayway.jsonpath.Configuration configuration() {
return com.jayway.jsonpath.Configuration.builder()
.jsonProvider(new JacksonJsonProvider())
.mappingProvider(new JacksonMappingProvider())
.options(EnumSet.noneOf(Option.class))
.build();
}
}
Your WeatherForCityIT should remain as in you sample code:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = IntegrationTestConfig.class)
public class WeatherForCityIT {
// your code here...
}
Regarding the exception message you are receiving:
No qualifying bean of type 'com.jayway.jsonpath.Configuration' available: expected single matching bean but found 2: getConfiguration,configuration)
From the error message you know that you have 2 beans of the same type (com.jayway.jsonpath.Configuration
) in your context:
The bean configuration is defined in your IntegrationTestConfig, the other bean getConfiguration is defined in one of your configuration classes. Somewhere in your application you are autowiring 'com.jayway.jsonpath.Configuration' bean by type. Since you have 2 beans of this type, Spring is complaining with the exception.
Do you need both of these beans? If not, delete one of the beans. Otherwise consider using @Qualifier annotation when autowiring beans.