我正在编写一个Junit测试框架来测试Web服务。
要求输入值来自许多不同的来源,例如早期的Web服务调用或类中的文字。
为实现这一目标,我的构造函数以不同的方式接受不同的输入;到目前为止一切都很简单。
问题是web服务还需要使用完整数据加载和必须的字段有效负载。
而不是在if
语句决定是否设置值的情况下乱丢(在某些情况下是冗长的)测试,我写了一个注释@Optional。
添加此注释会使其被以下代码置零:
/**
* Find all of the fields annotated with optional and null them
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
private void blankOptionalFields() throws IllegalAccessException{
for(Field field: this.getClass().getDeclaredFields()){
Annotation optionalAnnotation = field.getAnnotation(Optional.class);
if(!(field.isSynthetic()) && optionalAnnotation instanceof Optional){
field.setAccessible(true);
try{
field.set(this, null);
}
catch(IllegalArgumentException e){
logger.debug("Tried to set a scalar field to null!", e);
}
}
}
}
所以有两件事:
1:虽然这有效但感觉很脆弱/危险,但必须有更好的方法吗? 2:如果这不是一种愚蠢的方法,那么设置标量值以适应值的最佳方法是什么?
答案 0 :(得分:1)
如何定义一个只包含一个空白可选属性的方法的界面呢?您可以测试对象以实现接口并直接调用该方法。
这比使用反射创建捕获所有情况更优雅地处理特定异常:
interface Blankable {
/** @return true if all optional fields are successfully blanked. **/
public boolean blankOptionalFields();
}
并使用如:
if (obj implements Blankable) {
if (!((Blankable) obj).blankOptionalFields()) {
logger.debug("Could not blank optional fields for " + obj);
}
}
答案 1 :(得分:0)
我会重构测试,从实际测试代码中分离出初始化代码。就此而言,您可以将实际测试代码(调用Web服务的代码)放入多个测试方法之间共享的方法中。
作为一个半相关的评论:我认为“单元”测试是独立运行服务方法,而“集成”测试则将其作为实际的Web服务来运用。
答案 2 :(得分:0)
我并不喜欢这种方法,因为您将测试代码与生产代码混合在一起。
如果您知道哪些字段是提前强制的,是否可以在设置它们时循环遍历这些字段而不使用复杂的if结构?