与“不”一起使用的自定义hamcrest匹配器?

时间:2013-05-21 10:18:36

标签: java unit-testing junit hamcrest

我有一些课(比如,Entity)。

我希望能够

  1. 使用一些自定义代码来确定
  2. ,测试其实例是否“有效”
  3. 还测试实例无效,理想情况下使用相同的代码。
  4. 使用maven,surefire,JUnit 4.11(以及随附的hamcrest内容)。

    所以我写了一个类似这样的课程

    class IsValidEntity extends TypeSafeMatcher<Entity>{
    
        @Override public boolean matchesSafely(Entity e){
           // and here I do a bunch of asserts...
           assertNotNull(e.id);
           // etc.
        }
    
        @Override
        public void describeTo(Description description) {
           description.appendText("is valid entity");
        }
    
        @Factory
        public static <T> Matcher<Entity> validEntity() {
            return new IsValidEntity();
        } 
    }
    

    好的,好的,我可以做

    assertThat(entity, is(validEntity()); 
    

    在JUnit测试中,桃子。

    但我做不到

    assertThat(entity, not(validEntity());
    

    因为validEntity因断言失败而失败,而不是我猜它应该只是return false

    显然我在这里做了一些事情,但我不确定这些自定义匹配器的最聪明方法是什么。或者我可能根本不应该使用TypeSafeMatcher,而是做一些与众不同的事情?

3 个答案:

答案 0 :(得分:4)

应该重写matchesSafely方法以避免抛出断言失败。相反,只需手动执行检查,然后在必要时返回false

然后,你可以以你想要的方式否定它而没有后果。

答案 1 :(得分:3)

您不应该在assert中使用matchesSafely方法。你应该只做布尔逻辑来返回true或false。调用代码的责任是抛出断言错误和/或包装在not中。因此你应该做这样的事情:

public boolean matchesSafely(...){
       boolean result = true;
       result &= value1 == value2;
       result &= entity.getVal2() == someOtherVal2;
       return result;
}

答案 2 :(得分:0)

虽然其他答案更正确,但另一种方法可能是在匹配器中捕获异常,然后在吞下异常时返回false,否则返回true。

这不太理想。