Java.util.Optional有任何Hamcrest Matcher吗?

23
我正在寻找一个Hamcrest Matcher来对返回java.util.Optional类型的方法进行单元测试。类似于以下内容:
    @Test
    public void get__Null(){

        Optional<Element> element = Element.get(null);      
        assertThat( sasi , isEmptyOptional());
    }

    @Test
    public void get__GetCode(){

        Optional<Element> element = Element.get(MI_CODE);       
        assertThat( sasi , isOptionalThatMatches(allOf(hasproperty("code", MI_CODE),
                                                       hasProperty("id",   notNullValue())));
    }

是否有可在Maven仓库中使用的实现?


为什么不直接使用 equalTo(...) 呢? - Jaroslaw Pawlak
有其他测试对象的方法。但在某些情况下,匹配器会让我们的生活更轻松。例如,断言一个对象具有一个带有值的可选属性的bean,当您只想检查一些字段时。或者如果equals有一些特殊实现。 - borjab
我不太了解你的情况,但也许这个库可以帮到你:https://github.com/shazam/shazamcrest - Jaroslaw Pawlak
5个回答

19

目前Java Hamcrest正在使用1.6版本,并与使用旧版Java的许多项目集成。

因此,与Java 8相关的功能将在将来版本中添加,这些版本将兼容Java 8。提出的解决方案是拥有一个支持它的扩展库,这样任何需要的人都可以使用扩展库。

我是Hamcrest Optional的作者,现在已在Maven中心可用。

示例:检查Optional是否包含以某个值开头的字符串

import static com.github.npathai.hamcrestopt.OptionalMatchers.hasValue;
import static org.hamcrest.Matchers.startsWith;

Optional<String> optional = Optional.of("dummy value");
assertThat(optional, hasValue(startsWith("dummy")));

3

来自 Narendra Pathai 的 Hamcrest Optional 确实做得非常出色。

import static com.github.npathai.hamcrestopt.OptionalMatchers.isEmpty;
import static com.github.npathai.hamcrestopt.OptionalMatchers.isPresent;
import static com.github.npathai.hamcrestopt.OptionalMatchers.isPresentAnd;
import static com.github.npathai.hamcrestopt.OptionalMatchers.isPresentAndIs;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

  @Test
  public void testOptionalValue() {
    Optional<String> option = Optional.of("value");
    assertTrue(option.isPresent()); // the old-fashioned, non-diagnosable assertion
    assertThat(option, isPresent());
    assertThat(option, isPresentAndIs("value"));
    assertThat(option, isPresentAnd(startsWith("v")));
    assertThat(option, isEmpty()); // fails
  }

上述最后一个断言失败并且会输出一条清晰易懂的错误信息:
java.lang.AssertionError: 
Expected: is <Empty>
     but: had value "value"

可在Maven上使用:

<dependency>
  <groupId>com.github.npathai</groupId>
  <artifactId>hamcrest-optional</artifactId>
  <version>2.0.0</version>
  <scope>test</scope>
</dependency>

2

目前我有以下信息:

  • 在hamcrest网站上,有一个问题和一个功能提议,支持使用其他Java 8类型。
  • 一位用户创建了一个示例,并在他的GitHub上发布。尚未在Maven上,但正在努力解决。

2

如果这种方法能够被整合到Hamcrest中,或者如果你无法添加外部库。如果你可以添加一个类,以下代码可以用于处理空的可选项。

class EmptyOptionalMatcher<T> extends BaseMatcher<Optional<T>> {

    private Optional<T> optionalActual;

    public EmptyOptionalMatcher() {
    }

    @Override
    public boolean matches(Object item) {
        optionalActual = (Optional<T>) item;

        if (optionalActual == null) {
            return false;
        }

        boolean empty = !optionalActual.isPresent();
        return empty;
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("optional is empty");
    }

    @Override
    public void describeMismatch(Object item, Description description) {
        if (optionalActual == null) {
            description.appendText(" optional was NULL?");
        } else {
            description.appendText(" was: " + optionalActual.get());
        }
    }

}

然后创建一个匹配器帮助类或常见类,其中包含此静态方法,您可以导入并使用:

public static <T> Matcher<? super Optional<T>> emptyOptional() {
    return new EmptyOptionalMatcher<>();
}

用法如下:

assertThat(someOptional, is(emptyOptional()));

或者作为负测试

assertThat(someOptional, is(not(emptyOptional())));

1
如果您只想验证某个对象的可选字段是否存在/不存在,可以使用以下习语:
预期对象:
public class BusinessObject {
    private Long id;
    private String name;
    private Optional<AnotherObject> anotherObject;
}

Hamcrest测试看起来像这样:

assertThat("BusinessObject is not as expected", businessObject, allOf(
                hasProperty("id", equalTo(1L)),
                hasProperty("name", equalTo("Some title")),
                hasProperty("anotherObject", hasProperty("present", equalTo(true)))
        ));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接