2

考虑以下代码:

final Foo foo = context.mock(Foo.class);

context.checking(new Expectations() {{
    one(foo).someMethod(with(aNonNull(List.class)));
}});

我试图建议someMethod使用 type 的非 null 参数调用它List<Bar>。但是,我无法找出正确的语法来指定列表包含 Bar 类型的对象。以下简单的尝试不是有效的代码:

final Foo foo = context.mock(Foo.class);

context.checking(new Expectations() {{
    one(foo).someMethod(with(aNonNull(List<Bar>.class)));
}});

有没有正确的方法可以做到这一点,还是我被迫添加@SuppressWarnings("unchecked")到我的测试方法中?

我很欣赏这不是严格意义上的 JMock 特定问题,但我想我会这样标记它以吸引那些过去可能遇到过这个问题的人。

4

2 回答 2

2

泛型信息在运行时被删除 [JB]Effective Java SE p.l14。所以你必须以另一种方式检查。

我找到了这种方法来检查列表中所有元素的类型:

final Foo foo = context.mock(Foo.class);

context.checking(new Expectations() {{
    oneOf(foo).someMethod((List<Object>) with(Every.everyItem(IsInstanceOf.instanceOf(Bar.class))));
}});
于 2012-02-13T16:07:45.670 回答
0

至少有一些方法可以集中抑制警告。例如,您可以子类化Expectations

public static class UncheckedExpectations extends Expectations {
    @SuppressWarnings("unchecked")
    public <T, U extends T> U withUnchecked(Matcher<T> matcher) {
        return (U) super.with(matcher);
    }
}

然后使用额外的方法:

context.checking(new UncheckedExpectations() {{
    one(foo).someMethod(withUnchecked(aNonNull(List.class)));
}});

这仍然是泛型的滥用,因为它在方法上使用了泛型类型参数,而该方法实际上并未在参数中使用,并且仅在不安全强制转换的方法中使用。但是,它至少确实以一种不需要将相同的抑制注释分散在整个代码中的方式避开了这个问题。

Hamcrest 当然也可以让他们的with()方法像这样工作。他们没有这样做有点遗憾,因为 Hamcrest 代码上未经检查的警告在使用该库的任何代码库中都很常见。

于 2019-06-03T06:30:52.297 回答