在Junit中使用assertThat方法的时候第二个参数是一个hamcrest的Matcher 让Junit断言具有了很高的灵活性和可扩展性。
这里扩展一个大小比较的Matcher
首先自定义一个Matcher继承hamcrest的org.hamcrest.BaseMatcher
分别实现matches 和 describeTo
@Override public boolean matches(Object actual) { // 是否通过assert } @Override public void describeTo(Description description) { // 没有通过显示的信息 }在Junit使用即可
功能: 实现一个大于 大于等于 小于 小于等于的Matcher
这里我使用了策略模式将具体的比较行为抽离成一个比较器,核心就是根据matches方法返回的boolean值判断是否断言成功
public class ComparatorMatcher<T extends Number> extends BaseMatcher<T> { public class ComparatorMatcher<T extends Number> extends BaseMatcher<T> { // 期望值 private final T expected; private final Comparator<? super Number> comparator; private Object actual; public ComparatorMatcher(T expected, Comparator<Number> comparator) { this.expected = expected; this.comparator = comparator; } @Override public boolean matches(Object actual) { this.actual = actual; if (actual instanceof Number) { Number actualNum = (Number) actual; return comparator.compare(expected, actualNum); } throw new UnsupportedOperationException(" not a number "); } @Override public void describeTo(Description description) { description.appendText(String.format(" compactor error expected %s actual %s", String.valueOf(this.expected), String.valueOf(actual))); } @Factory public static <T extends Number> ComparatorMatcher<T> gt(T expected) { return new ComparatorMatcher<>(expected, new GtComparator<>(false)); } @Factory public static <T extends Number> ComparatorMatcher<T> lt(T expected) { return new ComparatorMatcher<>(expected, new LtComparator<>(false)); } @Factory public static <T extends Number> ComparatorMatcher<T> gte(T expected) { return new ComparatorMatcher<>(expected, new GtComparator<>(true)); } @Factory public static <T extends Number> ComparatorMatcher<T> lte(T expected) { return new ComparatorMatcher<>(expected, new LtComparator<>(true)); } } // 比较器接口 public interface Comparator<T extends Number> { boolean compare(T excepted, T actual); } // 大于比较器 public class GtComparator<T extends Number> implements Comparator<T> { private boolean isGte; public GtComparator(boolean isGte) { this.isGte = isGte; } @Override public boolean compare(T excepted, T actual) { if (isGte) { return actual.doubleValue() >= excepted.doubleValue(); } return actual.doubleValue() > excepted.doubleValue(); } } // 小于比较器 public class LtComparator<T extends Number> implements Comparator<T> { private boolean isLte; public LtComparator(boolean isLte) { this.isLte = isLte; } @Override public boolean compare(T excepted, T actual) { if (isLte) { return actual.doubleValue() <= excepted.doubleValue(); } return actual.doubleValue() < excepted.doubleValue(); } } // Junit 测试 public class TestCustomComparatorMatcher { @Test public void testMyMatcher() { assertThat(2, gt(1)); assertThat(2, gte(2)); assertThat(2, lt(4)); assertThat(2, lte(4)); assertThat(2, lte(2)); } }