2012-03-15 125 views
2

我製作了一個MethodRule和@ Rule-annotation,可以讓我的測試生活變得更輕鬆。 它檢查是否拋出了特定的異常,並檢查異常消息是否等於或包含給定的消息。JUnit MethodRule只測試一行

現在,當我運行testmethod多行測試時,它只需要第一行,並準備好了。我如何製作測試方法中的所有線?

這是我的代碼: 註釋:

@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.METHOD}) 
public @interface ExpectedDomeinValidatieMessage { 
    String value() default ""; 
    String contains() default ""; 
} 

MethodRule:

@Override 
public Statement apply(final Statement base, final FrameworkMethod method, final Object target) { 
return new Statement() { 

    @Override 
    public void evaluate() throws Throwable { 
    ExpectedDomeinValidatieMessage message = method.getAnnotation(ExpectedDomeinValidatieMessage.class); 
    if (message == null) { 
     base.evaluate(); 
    } else { 
     try { 
     base.evaluate(); 
     Assert.fail("DomeinValidatieException not thrown"); 
     } catch (DomeinValidatieException e) { 
     if (StringUtils.isNotBlank(message.value())) { 
      if (!e.getMessage().equals(message.value())) { 
      throwException(e, "", message.value(), e.getMessage()); 
      } 
     } 
     if (StringUtils.isNotBlank(message.contains())) { 
      if (!e.getMessage().contains(message.contains())) { 
      throwException(e, "Segment niet gevonden:", message.contains(), e.getMessage()); 
      } 
     } 
     } 
    } 
    } 

    private void throwException(Throwable exception, String message, String expected, String actual) { 
    ComparisonFailure cf = new ComparisonFailure(message, expected, actual); 
    cf.setStackTrace(exception.getStackTrace()); 
    throw cf; 
    } 
}; 

用法:

@Test 
@ExpectedDomeinValidatieMessage("[Werkzaamheden] WerkzaamMetGevaarlijkeStoffen niet gevuld") 
public void valideerWerkzaamMetGevaarlijkeStoffen() throws DomeinValidatieException { 
    aanvraag.getVerzekerde().getWerkzaamheden().setWerkzaamMetGevaarlijkeStoffen(null); 
    validator.valideer(); 
} 

如果我這樣使用它,它只是測試首測在方法中:

@Test 
@ExpectedDomeinValidatieMessage("[Werkzaamheden] WerkzaamMetGevaarlijkeStoffen niet gevuld") 
public void valideerWerkzaamMetGevaarlijkeStoffen() throws DomeinValidatieException { 
    aanvraag.getVerzekerde().getWerkzaamheden().setWerkzaamMetGevaarlijkeStoffen(null); 
    validator.valideer(); //Only this one is tested 
    aanvraag.getVerzekerde().getWerkzaamheden().setWerkzaamMetGevaarlijkeStoffen("bla"); 
    validator.valideer(); //This is NOT tested 
} 

回答

0

JUnit assertXXX方法通過拋出異常(特別是AssertionError)來工作。所以當拋出一個異常(通過你的代碼或者斷言)時,控制會退出測試方法。沒有任何方法可以從拋出異常的位置重新啓動。

您可能想要Parameterized,它允許您使用不同的參數多次運行相同的測試。

編輯:我懷疑valideer()拋出一個異常。爲了進一步解釋,讓我們來解釋一下你的代碼。當你定義的規則,你要切實做好如下:

try { 
    base.evaluate(); // this calls valideerWerkzaamMetGevaarlijkeStoffen() 
    Assert.fail("DomeinValidatieException not thrown"); 
} catch (DomeinValidatieException e) { 
    // evaluate whether or not the test has failed or not 
} 

這意味着,如果你第一次調用valideer()拋出一個異常,則控制上面轉移到catch塊。沒有機會繼續執行測試,因爲控制已經通過別處。您可以儘可能多地通過/不通過測試,但控制已傳遞到上面的catch塊。

順便說一句,MethodRule已被棄用在更高版本中,您應該使用TestRule來代替。

+0

馬修,你描述失敗的情況。當然,它會停止,那是預料之中的。但是當第一條測試線是好的時候,第二條線沒有經過測試。 – 2012-03-15 08:28:50

+0

編輯答案包括更好的解釋發生了什麼事。 – 2012-03-15 09:20:43

+0

我想我明白了。當然它會拋出異常並通過控制。所以我已經超越了沒有回報的地步,因爲這不會被記錄爲錯誤。我會看看TestRule。 – 2012-03-15 10:27:07

0

通過調試器運行代碼。我的猜測是,第一次打電話給valideer()確實會拋出異常,即使你不期望它。

+0

亞倫我認爲你是對的。正如預期的那樣,它拋出了DomeinValidatieException。所以可能這就是爲什麼只採取第一個可測試的LoC。現在我必須找到一種方法來抑制增加的錯誤... – 2012-03-15 09:12:57

+0

將它分成兩個測試 – 2012-03-15 10:09:52