2010-01-20 61 views
1

我正在编写一个Junit测试框架来测试Web服务。带反射的空白字段

要求输入值来自许多不同的来源,例如较早的Web服务调用或类内的文字。

为了实现这一点,我有构造函数以不同的方式接受不同的输入;迄今为止都很简单。

问题是Web服务还需要执行一个完整的数据加载和一个必填字段只有有效载荷。

而不是使用if语句来判断是否设置一个值,但我已经写了一个注释@Optional,而不是使用(在某些情况下是verrry long)测试。

添加此注释导致其通过下面的代码被清零:

 /** 
    * 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:如果这不是一个拙劣的方法,那么将标量值设置为合适的值的最好方法是什么?

回答

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); 
    } 
} 
+0

我对这个解决方案不知情。我不清楚为什么我没有首先想到这一点。 – 2010-01-20 16:04:56

0

我会重构测试,从实际测试代码中分离出初始化代码。对于这个问题,你可以把实际的测试代码(调用Web服务的代码)放到一个在多个测试方法之间共享的方法中。

作为一个半相关的评论:我认为“单元”测试是单独使用服务方法,而“集成”测试可以将其作为一种实际的Web服务使用。

+0

我喜欢出去分裂初始化代码的想法,但不幸的是,实际的测试代码不能共享。关于“单元”测试的公平点 – 2010-01-20 15:37:11

0

我并不迷恋这种方法,因为您将测试代码与生产代码混合在一起。

如果你知道哪些字段是强制性的,那么是否有可能在没有复杂的if结构的情况下循环这些字段?

+0

没有涉及生产代码,它的所有测试代码。我可以遍历字段并设置它们,但是从什么来源设置它们?我将不得不编写每个输入的设置代码 – 2010-01-20 15:35:28