我在Web应用程序中使用了远程api。某些端点在我使用的API中需要身份验证标头。由于这种需要,我在配置类中创建了两个不同的RestTemplateBuilder bean。
@Configuration
public class RestTemplateConfiguration {
@Bean
@DependsOn(value = {"secureRestTemplateCustomizer"})
@Qualifier("secureRestTemplateBuilder")
public RestTemplateBuilder secureRestTemplateBuilder() {
return new RestTemplateBuilder(secureRestTemplateCustomizer());
}
@Bean
@DependsOn(value = {"publicRestTemplateCustomizer"})
@Qualifier("publicRestTemplateBuilder")
public RestTemplateBuilder publicRestTemplateBuilder() {
return new RestTemplateBuilder(publicRestTemplateCustomizer());
}
@Bean
@Qualifier("secureRestTemplateCustomizer")
public SecureRestTemplateCustomizer secureRestTemplateCustomizer() {
return new SecureRestTemplateCustomizer();
}
@Bean
@Qualifier("publicRestTemplateCustomizer")
public PublicRestTemplateCustomizer publicRestTemplateCustomizer() {
return new PublicRestTemplateCustomizer();
}
}
这些是我的自定义RestTemplateCustomizers
@Component
public class SecureRestTemplateCustomizer implements RestTemplateCustomizer {
@Override
public void customize(RestTemplate restTemplate) {
restTemplate.setErrorHandler(new ErrorHandler());
restTemplate.getInterceptors().add(new AuthorizationHeaderInterceptor());
}
}
PublicRestTemplateCustomizer
@Component
public class PublicRestTemplateCustomizer implements RestTemplateCustomizer {
@Override
public void customize(RestTemplate restTemplate) {
restTemplate.setErrorHandler(new ErrorHandler());
}
}
当我想在如下所示的api客户端中使用这些RestTemplateBuilder
时没有问题。 Spring可以将它们自动连接到我的api客户端构造函数中。
private RestTemplate restTemplate;
@Autowired
public LoginApiClient(@Qualifier("publicRestTemplateBuilder") RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build();
}
但是在我的单元测试中,这种用法引发了
之类的错误。创建文件[.. \ LoginApiClient.class]中定义的名称为'loginApiClient'的bean时出错:通过构造函数参数0表示的不满足的依赖关系;嵌套的异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有类型为“ org.springframework.boot.web.client.RestTemplateBuilder”的合格Bean:至少应有1个可以作为自动装配候选的bean。依赖项注释:{@ org.springframework.beans.factory.annotation.Qualifier(value = publicRestTemplateBuilder)}
@RunWith(SpringRunner.class)
@RestClientTest({LoginApiClient.class})
@Category(IUnitTest.class)
public class LoginApiClientTest {
@Autowired ILoginApiClient loginApiClient;
@Autowired private MockRestServiceServer server;
@Test
public void validateToken_returns_true_for_valid_token() throws Exception{
String token = "token";
this.server.expect(requestTo(this.validateTokenUrl))
.andExpect(method(HttpMethod.POST))
.andRespond(withSuccess(objectMapper.writeValueAsString(validTokenResponse(token)), MediaType
.APPLICATION_JSON));
Boolean isValid = loginApiClient.validateToken(token);
server.verify();
assertThat(isValid,is(equalTo(true)));
}
}
如何真正模拟这些RestTemplate并在单元测试中使用。
答案 0 :(得分:0)
我认为您在主应用程序类中缺少@ComponentScan(value =“ your.package”)
答案 1 :(得分:0)
您没有指定上下文。
尝试将此注释添加到您的测试类中:
@ContextConfiguration(classes=RestTemplateConfiguration.class, loader=AnnotationConfigContextLoader.class)
有关详细信息,请参见本文:spring-3-1-m2-testing-with-configuration-classes-and-profiles-适用于Spring 3,但较新版本的Spring的工作原理类似。
这是较新的教程:junit-spring-integration-example