我碰到https://code.google.com/p/hamcrest/issues/detail?id=130为Hamcrest匹配器添加了一些糖语法。但是这个想法被Hamcrest开发人员拒绝了。

还有其他聪明的主意,可以避免不必在多头后面输入L,从而使测试更具可读性吗?

@Test
public void test1() {
    int actual = 1;
    assertThat(actual, is(1));
}

@Test
public void test2() {
    long actual = 1L;
    assertThat(actual, is(1)); // fails as expected is <1> but result was <1L>
    // assertThat(actual, is(1L)); off course works..
}

@Test
public void test3() {
    Long actual = new Long(1);
    assertThat(actual, is(1)); // fails as expected is <1> but result was <1L>
}

更新

比较时,例如,请参见下文中的差异。 int和long使用默认Java语言(==),标准junit assert(assertTrue)和hamcrest is()方法。似乎奇怪的hamcrest不支持匹配/比较long与int,而其余的则是。
@Test
public void test2() {
    long actual = 1L;
    int expected = 1;
    assertTrue(expected == actual); // std java succeeds
    assertEquals(expected, actual); // std junit succeeds
    assertThat(actual, is(expected)); // hamcrest fails: Expected: is <1> but: was <1L>
}

最佳答案

这与您链接的问题(与解决有问题的静态分析仪有关)完全无关,并且已被正确拒绝。混合基本类型时,Java中很常见您遇到的问题。

为了避免键入L,您必须提供所有匹配器的重载版本,而不仅仅是is。考虑以下示例:

assertThat(longValue, greaterThan(1));
assertThat(longList, contains(1, 2, 3));

更新

您可以轻松添加自己的重载版本来执行转换:
public static Matcher<Long> is(Integer value) {
    return org.hamcrest.core.Is.is(value.longValue());
}

当然,现在您已经可以将int转换为long,您将需要使用floatdouble进行转换:
public static Matcher<Long> is(Float value) {
    return org.hamcrest.core.Is.is(value.longValue());
}

public static Matcher<Long> is(Double value) {
    return org.hamcrest.core.Is.is(value.longValue());
}

由于Java不会自动将byte转换为Integer *,因此,您还需要byteshort的版本。这很丑陋,但是如何转换为其他类型(例如,从intdouble)呢?
public static Matcher<Double> is(Integer value) {
    return org.hamcrest.core.Is.is(value.doubleValue());
}



哦,哦!这些将不起作用,因为Java不允许您根据返回类型重载方法。您必须在单独的类中声明这些方法,这些方法留给您。

考虑到这将造成巨大的困惑,我怀疑Hamcrest的作者是否会因为低 yield 而愿意接受这样的增加。坦率地说,最好通过根据需要使用1L1.0进行显式表示。

*虽然编译器会将byte转换为int,但可以装箱到Integer

关于java - 如何在Hamcrest中使用(原始)自动装箱/加宽?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26437839/

10-12 03:57