【发布时间】:2020-12-01 22:52:13
【问题描述】:
我想为我的网关云过滤器编写 junit 测试,但问题是我是单元测试的新手。请帮我。这是一种私有的授权方法。
[如果有人不知道如何编写spring Gateway云过滤器,那么请通过我的网关过滤器方法。和逻辑]
@Component
@Slf4j
public class AuthorizationFilter extends AbstractGatewayFilterFactory<AuthorizationFilter.Config> {
@Value("${rest.auth.service.url}")
private String authServiceUrl;
@Autowired
RestTemplate restTemplate;
public AuthorizationFilter() {
super(Config.class);
}
private Mono<Void> onError(ServerWebExchange exchange, String err, HttpStatus httpStatus) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(httpStatus);
return response.setComplete();
}
//Here is my authorization details
private UserRoleDetailsDTO getAuthorizationDetails(String authorizationHeader) {
try {
log.error("Checking authorization");
HttpEntity<?> entity = new HttpEntity(null, new HttpHeaders() {{
add("Authorization", authorizationHeader);
add("Accept", "application/json");
}});
ResponseEntity<Map> responseMap = restTemplate.exchange(authServiceUrl.concat("/v1/profile"), HttpMethod.GET, entity, Map.class);
System.out.println(responseMap);
if (responseMap.getBody() == null)
log.warn("Received null body in response. Request will end now");
Map data = (Map) responseMap.getBody().get("data");
boolean isAuthorized = data.get("authorized") == null || (boolean) data.get("authorized");
UserRoleDetailsDTO userRoleDetailsDTO = UserRoleDetailsDTO.builder().userId(String.valueOf(data.get("userId"))).
roles((List<RoleDTO>) data.get("roles")).isAuthorized(isAuthorized).build();
return userRoleDetailsDTO;
} catch (RestClientException e) {
String errorResponse = null;
if (e instanceof HttpClientErrorException) {
HttpClientErrorException exception = (HttpClientErrorException) e;
errorResponse = exception.getResponseBodyAsString();
} else errorResponse = e.getMessage();
log.error("error with http connect with error response : {} : {}", errorResponse, e);
return null;
} catch (Exception e) {
log.error("error with http connect : {}", e);
return null;
}
}
// Here is my Gateway filter
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
String requestId;
if (request.getHeaders().containsKey("Request-Id")) {
requestId = request.getHeaders().get("Request-Id").get(0);
} else {
requestId = UUID.randomUUID().toString();
log.debug("Request Id not passed. {} is genertaing requestId {}", AuthorizationFilter.class.getSimpleName(), requestId);
}
MDC.put("requestId", requestId);
request.mutate().header("Request-Id", requestId);
if (!request.getHeaders().containsKey("Authorization")) {
log.error("No authorization header");
return onError(exchange, "No Authorization header", HttpStatus.UNAUTHORIZED);
}
String authorizationHeader = request.getHeaders().get("Authorization").get(0);
UserRoleDetailsDTO userRoleDetailsDTO = getAuthorizationDetails(authorizationHeader);
if (userRoleDetailsDTO == null || !userRoleDetailsDTO.isAuthorized()) {
log.error("Invalid authorization header");
return onError(exchange, "Invalid Authorization header", HttpStatus.UNAUTHORIZED);
}
String userDetailsStr = "";
try {
userDetailsStr = new ObjectMapper().writeValueAsString(userRoleDetailsDTO);
System.out.println("value 1 :"+userDetailsStr);
} catch (JsonProcessingException e) {
log.error("Exception writing user details to string. ", e);
}
if (StringUtils.isEmpty(userDetailsStr))
log.warn("Empty User Details string being passed!!");
request.mutate().header(ApplicationConstants.USER_DETAILS_HEADER, userDetailsStr);
System.out.println("value 2 :"+request.mutate().header(ApplicationConstants.USER_DETAILS_HEADER, userDetailsStr));
return chain.filter(exchange.mutate().request(request).build());
};
}
@Override
public Config newConfig() {
return new Config();
}
public static class Config {
// Put the configuration properties
}
}
这是我的用户角色详细信息
public class UserRoleDetailsDTO {
private String userId;
private List<RoleDTO> roles;
private boolean isAuthorized = true;
}
和 RoleDto 类
public class RoleDTO {
private String name;
private int weight;
}
这是我运行代码覆盖率时的 junit 测试,然后我没有得到完全的代码覆盖率,请帮助我
public YourClassTest{
@Test
void apply() throws Exception {
AuthorizationFilter authorizationFilter = new AuthorizationFilter();
AuthorizationFilter.Config config = new YourClass.Config();
GatewayFilter filter =authorizationFilter.apply(config);
String st ;
st = new ObjectMapper().writeValueAsString(userRoleDetailsDTO);
MockServerHttpRequest expected = MockServerHttpRequest.get("/v1/profile").
header("Authorization", "Bearer sdfsf",st, TestConstants.USER_DETAILS_HEADER).build();
MockServerWebExchange exchange = MockServerWebExchange.from(expected);
filter.filter(exchange,FilterChain);
String requestid;
ServerHttpRequest actual = exchange.getRequest();
assertEquals(expected,actual);
}
}
【问题讨论】:
-
你应该更新标题说帮助我在单元测试中获得完整的代码覆盖率。正如标题所示,您需要帮助编写测试。由于 if 语句和异常处理,您可能需要使用不同的模拟请求进行多次测试才能获得全面覆盖。
-
感谢 spencergibb 提供建议
标签: spring-boot unit-testing spring-cloud junit5 spring-cloud-gateway