我有这样的映射:
@GetMapping(value = "/topics", params = "dateRange")
public Set<Integer> getTopicsInRange(@RequestParam DateRange dateRange) {
return topicService.getTopicsInRange(dateRange);
}
现在我想将其测试为:
private final static DateRange VALID_DATE_RANGE = new DateRange(LocalDate.of(2018, 1, 1), LocalDate.of(2018, 2, 2));
@Test
public void gettingTopicsInRangeShouldReturn200(){
given().
.when()
.get(String.format("/topics?dateRange=%s", VALID_DATE_RANGE)
.then()
.statusCode(200);
}
Expected status code <200> doesn't match actual status code <400>.
我知道,如果将DateRange参数更改为2个单独的参数,我的解决方案将起作用:
@GetMapping(value = "/topics", params = {"begin", "end"})
public Set<Integer> getTopicsInRange(@RequestParam Date begin, @RequestParam Date end) {
return topicService.getTopicsInRange(begin, end);
}
,然后将其测试为/topics?begin=value&end=value2
,但这不是我想要的(如果DateRange想要10个字段进行10个参数的设置,我认为确实太过分了)
有什么想法可以解决我的问题吗?
编辑 这是我的DateRange类:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DateRange {
LocalDate begin;
LocalDate end;
}
答案 0 :(得分:2)
添加DateTimeFormat
批注:
public class DateRange {
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate begin;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate end;
// getter and setters
}
在控制器中接收对象:
@GetMapping(value = "/topics")
public Set<Integer> getTopicsInRange(DateRange dateRange) {
return topicService.getTopicsInRange(dateRange);
}
并分别发送参数:
@Test
public void gettingTopicsInRangeShouldReturn200() {
given()
.queryParams("begin", LocalDate.of(2018, 1, 1).format(ISO_DATE),
"end", LocalDate.of(2018, 2, 2))
.when()
.get("/topics")
.then()
.statusCode(200);
}
答案 1 :(得分:0)
您需要一种将DateRange类转换为String的方法,反之亦然。由于您使用的是Spring,因此可以这样操作:
1)添加转换逻辑
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DateRange {
LocalDate begin;
LocalDate end;
private static final String DELIMITER = "_";
public static DateRange fromFormattedString(String source) {
if (source != null) {
String[] tokens = source.split(DELIMITER);
if (tokens.length == 2) {
return new DateRange(
LocalDate.parse(tokens[0]), // begin
LocalDate.parse(tokens[1]) // end
);
}
}
return null;
}
public String toFormattedString() {
return begin + DELIMITER + end;
}
}
2)创建Spring转换器
import org.springframework.core.convert.converter.Converter;
public class DateRangeConverter implements Converter<String, DateRange> {
@Override
public DateRange convert(String source) {
return DateRange.fromFormattedString(source);
}
}
3)注册此转换器
这将允许Spring处理以@RequestParam
-s传递的DateRange对象
@Configuration
public class WebApiConfiguration extends WebMvcConfigurationSupport {
...
@Override
public FormattingConversionService mvcConversionService() {
FormattingConversionService f = super.mvcConversionService();
f.addConverter(new DateRangeConverter());
return f;
}
...
}
最后使用:
.get(String.format("/topics?dateRange=%s", VALID_DATE_RANGE.toFormattedString())
或(使用原始字符串):
.get(String.format("/topics?dateRange=%s", "2018-1-1_2018-2-2")
但是:
尽管如此,我还是建议您使用单独的请求参数(开始,结束等),即使它们有10个,因为它是:
1)RESTful方式
2)防错,因为传递了订单请求参数,所以并不严格。另一方面,将参数打包到单个对象中将迫使您注意参数顺序。此外,您必须将所有参数打包为字符串,因此不允许使用任何可选参数,否则拆包逻辑可能会被破坏