I have a service which uses an autowired instance of RestTemplate
like below
@Service
class SomeAPIService {
private RestTemplate restTemplate;
SomeAPIService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
this.restTemplate.setRequestFactory(HttpUtils.getRequestFactory());
}
}
Everything runs fine in non-test environment. But when I try to run following unit test in test profile, it starts complaining about unable to autowire rest template.
@RunWith( SpringJUnit4ClassRunner.class )
@SpringBootTest(classes = MyApplication.class, webEnvironment = RANDOM_PORT, properties = "management.port:0")
@ActiveProfiles(profiles = "test")
@EmbeddedPostgresInstance(flywaySchema = "db/migration")
public abstract class BaseTest {
}
@SpringBootTest(classes = SomeAPIService.class)
public class SomeAPIServiceTest extends BaseTest {
@Autowired
SomeAPIService someAPIService;
@Test
public void querySomeAPI() throws Exception {
String expected = someAPIService.someMethod("someStringParam");
}
}
Following is the detailed exception -
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'someAPIService': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.web.client.RestTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Any clues?
Following helped me get the correct dependencies autowired. The solution is to also include RestTemplate.class
in list of classes given to SpringBootTest
.
@SpringBootTest(classes = {RestTemplate.class, SomeAPIService.class})
class SomeAPIService {
@Autowired
SomeAPIService someAPIService;
@Test
public void querySomeAPI() throws Exception {
String expected = someAPIService.someMethod("someStringParam");
}
}
@Emre answer was helpful in guiding me towards the final solution.
You are trying to autowire SomeAPIService without satisfying its dependencies. You should inject Rest Template to SomeAPIService. But you are getting NoSuchBeanDefinitionException for Rest Template.
Take a look how to inject it :
Alternative answer would be - to use TestRestTemplate
TestRestTemplate
can be instantiated directly in your integration tests, as shown in the following example:
public class MyTest {
private TestRestTemplate template = new TestRestTemplate();
@Test
public void testRequest() throws Exception {
HttpHeaders headers = this.template.getForEntity(
"https://myhost.example.com/example", String.class).getHeaders();
assertThat(headers.getLocation()).hasHost("other.example.com");
}
}
Alternatively, if you use the @SpringBootTest
annotation with WebEnvironment.RANDOM_PORT
or WebEnvironment.DEFINED_PORT
, you can inject a fully configured TestRestTemplate
and start using it. If necessary, additional customizations can be applied through the RestTemplateBuilder
bean.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.