Hamcrest IsNot匹配器与一个包装的自定义匹配器 - describeMismatch不能按预期工作

时间:2014-08-08 12:05:38

标签: java junit hamcrest

最近我为jaxb生成的元素制作了一个自定义匹配器,并且遇到了这种情况:

前提条件:

  • 我有一个自定义Matcher,使用覆盖方法describeTo和describeMismatch扩展BaseMatcher(当然也匹配..)
  • 我正在使用assertThat(actualObject,not(myMatchersStaticRunMethod(expectedObject))

当断言失败时,结果我有:

Expected: not myMatchersDescribeToDescription
but: isNotCoreMatcherDescribeMismatchDescription

挖掘org.hamcrest.core.IsNot类的代码我可以看到describeTo是正确实现的(即委托将描述收集到一个包装的匹配器),但是describeMismatch没有被覆盖,因此使用了BaseMatcher的版本。 / p>

Imho这是一个错误的行为,因为也应该从包装的匹配器中获取不匹配。伙计们,你觉得怎么样?

2 个答案:

答案 0 :(得分:0)

describeMismatch应该在Matcher超载Matchermatch接口指定describeToSelfDescribing(通过Matcher)。因此,Hamcrest框架不会尝试通过Matcher来获取实际对象的描述,而只是{{1}}本身的描述。

答案 1 :(得分:0)

我不知道为什么这会被拒绝。我同意这是错误的行为。似乎与this issue

类似

您只能通过创建自己的自定义" notD"来修复它。 matcher,它是IsNot匹配器的副本,为describeMismatch添加了覆盖:

import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;

import static org.hamcrest.core.IsEqual.equalTo;


/**
 * Calculates the logical negation of a matcher.
 */
public class IsNotDescribing<T> extends BaseMatcher<T>  {
    private final Matcher<T> matcher;

    public IsNotDescribing(Matcher<T> matcher) {
        this.matcher = matcher;
    }

    @Override
    public boolean matches(Object arg) {
        return !matcher.matches(arg);
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("not ").appendDescriptionOf(matcher);
    }

    // use the matcher to describe its mismatch
    @Override
    public void describeMismatch(Object item, Description description) {
        matcher.describeMismatch(item, description);
    }

    @Factory
    public static <T> Matcher<T> notD(Matcher<T> matcher) {
        return new IsNotDescribing<T>(matcher);
    }

    @Factory
    public static <T> Matcher<T> notD(T value) {
        return notD(equalTo(value));
    }
}