2010-01-20 44 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