【问题标题】:Custom hamcrest matcher that works with "not"?与“不”一起使用的自定义 hamcrest 匹配器?
【发布时间】:2013-05-21 10:18:35
【问题描述】:

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

我希望能够

  1. 测试该实例是否“有效”,使用一些自定义代码来确定
  2. 还要测试一个实例是否无效,最好使用相同的代码。

使用 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,而是做一些不同的事情?

【问题讨论】:

    标签: java unit-testing junit hamcrest


    【解决方案1】:

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

    然后,你可以以你想要的方式否定它而不会产生任何后果。

    【讨论】:

    • 是的,显然我可以做到,但是我不能使用其他聪明的断言方法来做我想做的检查。也许我应该做一些完全不同的事情来将一堆断言组合在一起?
    • @PapaFreud 如果您绝对必须使用断言来执行检查,那么您可以将它们包装在 try/catch 中并从您的 catch 子句中返回 false
    • 这就是我所做的,捕获一个 AssertionError 并返回 false。但是……如果我“绝对必须”使用断言呢?好吧,不,不是这样,但是...我正在使用 hamcrest 匹配器编写单元测试。在这种情况下,使用断言并没有让我觉得特别奇怪。是吗?
    • @PapaFreud 是的,在这种情况下是。您正在实现一个方法,其任务是返回一个布尔值,而不是抛出断言异常。如果您想通过 try/catch 中的断言来实现这一点并不重要,只要您返回 true 表示 OK 并且返回 false 表示否,那么一切都很好。
    • 好的。取点。但我这样做只是因为我想首先将断言组合在一起。正如我所说 - 也许我应该做一些不同的事情?
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      这并不理想。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多