2013-08-21 36 views
2

我正在寫一些自定義匹配器來簡化junit聲明。他們大多數擴展TypeSafeMatcher,所以我只需要覆蓋三種方法:如何測試自定義hamcrest匹配器?

public class NoneConstraintViolationMatcher<T> extends 
    TypeSafeMatcher<Set<ConstraintViolation<T>>> { 

    @Override 
    public void describeTo(Description description) { 
     description.appendText("None constraint violations found"); 
    } 

    @Override 
    protected void describeMismatchSafely(Set<ConstraintViolation<T>> item, 
     Description mismatchDescription) { 
     mismatchDescription. 
      appendText("Unexpected constraint violation found, but got "); 
     mismatchDescription.appendValueList("", ",", "", item); 
    } 

    @Override 
    protected boolean matchesSafely(Set<ConstraintViolation<T>> item) { 
     return item.isEmpty(); 
    } 
} 

我的問題是如何測試它們?我目前的解決方案是

public class NoneConstraintViolationMatcherUnitTests { 

    private NoneConstraintViolationMatcher<Object> matcher = 
     new NoneConstraintViolationMatcher<Object>(); 

    @Test 
    public void returnsMatchedGivenNoneConstraintViolations() throws Excetpion { 
     assertTrue(matcher.matches(.....)); 
    } 

    @Test 
    public void returnsMismatchedGivenSomeConstraintViolations() throws Excetpion { 
     assertThat(matcher.matches(.....), is(false)); 
    }   

    @Test 
    public void returnsConstraintViolationsFoundWhenMismatched() 
     throws Exception { 

     StringBuilder out = new StringBuilder(); 
     //I don't find anything could be used to assert in description 

     StringDescription description = new StringDescription(out); 

     matcher.describeMismatch(..someCvx, description); 

     assertThat(out.toString(), 
      equalTo("Unexpected constraint violation found, but got ")); 
    } 
} 

是在我腦海中的另一個解決方案是寫一個JUnit測試,並使用@rule的ExpectedException(與handleAssertionError設置爲true)。

你們如何測試匹配者?提前致謝。

回答

2

我使用assertThat來測試匹配功能。

@Test 
public void returnsMatchedGivenNoneConstraintViolations() throws Excetpion { 
    assertThat(someObject, matcher); 
} 

@Test 
public void returnsMismatchedGivenSomeConstraintViolations() throws Excetpion { 
    assertThat(someObject, not(matcher)); 
} 
+0

謝謝你的迴應。使用此解決方案測試描述是否容易? – Hippoom

0

要回答關於測試說明的後續問題,我不會在需要時看到此問題。我認爲它足夠寫你returnsConstraintViolationsFoundWhenMismatched測試這樣

@Test(expected=Exception.class) 
public void returnsConstraintViolationsFoundWhenMismatched() { 
    // Use the matcher in a way that causes an exception to be thrown 
} 

重要的驗證是正確的異常被拋出。測試實際消息的內容,並且不會爲測試套件添加任何值。你可以相信Hamcrest圖書館正在用你附加在描述中的文字做正確的事情。

+1

我有一種情況需要測試說明。這是因爲我正在檢查集合的內容,並且只想報告不匹配。更具體地說,我想檢查描述的邏輯(例如循環和條件),而不是生成的文本。邏輯應該匹配'matchesSafely'方法中的邏輯,但是在Java中重用邏輯代碼並不那麼簡單。 –

+0

如果matchesSafely的邏輯和描述的生成重疊,則可以在Hamcrest匹配器類中編寫一個私有方法來重用代碼。然後通過測試匹配器,你也隱含地測試產生描述的邏輯。 –

+0

對不起,當我說邏輯是相同的,我的意思是條件,而不是循環和條件的主體。例如'matchesSafely'可能有'if(A)return false; (B)返回錯誤;返回true;'while describeTo'將具有'if(A)description.appendText(「A」);如果(B)depscription.appendText(「B」);'。我認爲模板方法模式適合這裏,但它在Java(Java 8之前)中非常冗長。 –

相關問題