无法自动装配RestTemplate以进行单元测试

时间:2018-04-08 07:56:37

标签: java spring-boot junit mockito

我有一个服务,它使用RestTemplate的自动装配实例,如下所示

@Service
class SomeAPIService {
    private RestTemplate restTemplate;

    SomeAPIService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
        this.restTemplate.setRequestFactory(HttpUtils.getRequestFactory());
    }
}

在非测试环境中一切运行良好。但是当我尝试在测试配置文件中运行以下单元测试时,它开始抱怨无法自动恢复休息模板。

@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");
    }
}

以下是详细的例外情况 -

  

引起:   org.springframework.beans.factory.UnsatisfiedDependencyException:   创建名为'someAPIService'的bean时出错:不满意的依赖项   通过构造函数参数0表示;嵌套异常是   org.springframework.beans.factory.NoSuchBeanDefinitionException:没有   'org.springframework.web.client.RestTemplate'类型的限定bean   可用:预计至少有1个符合autowire资格的bean   候选人。依赖注释:{}

任何线索?

3 个答案:

答案 0 :(得分:3)

以下帮助我获得了自动连接的正确依赖项。解决方案是在RestTemplate.class的类列表中包含SpringBootTest

@SpringBootTest(classes = {RestTemplate.class, SomeAPIService.class})
class SomeAPIService {
    @Autowired
    SomeAPIService someAPIService;

    @Test
    public void querySomeAPI() throws Exception {
        String expected = someAPIService.someMethod("someStringParam");
    }
}

@Emre回答有助于指导我找到最终解决方案。

答案 1 :(得分:0)

您正试图在不满足其依赖性的情况下自动装配SomeAPIService。您应该将Rest模板注入SomeAPIService。但是你得到了Rest模板的NoSuchBeanDefinitionException。

看一下如何注射它:

How to autowire RestTemplate using annotations

答案 2 :(得分:0)

替代答案是-使用TestRestTemplate

From official docs >>>

TestRestTemplate可以在集成测试中直接实例化,如以下示例所示:

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");
    }

}

或者,如果将@SpringBootTest注释与WebEnvironment.RANDOM_PORTWebEnvironment.DEFINED_PORT一起使用,则可以注入完全配置的TestRestTemplate并开始使用它。如有必要,可以通过RestTemplateBuilder bean来应用其他自定义。