`

关于hamcrest断言的不足

阅读更多
hamcrest断言提供了很多好用的断言表达式,参见http://0411.iteye.com/blog/1048303

我最感兴趣的是对集合中Bean属性的断言,相信这也是最具实用的断言,可见hamcrest偏偏在这方面做得很弱啊,以下是我的一断测试代码:

    @Test
    public void testNotSeniorQuery() throws Exception {
        List<ParsedQueryParam> parsedQueryParams = queryParamParser.parse(request);
        assertThat(parsedQueryParams, notNullValue());
        assertThat(parsedQueryParams, hasSize(6));
        assertThat(parsedQueryParams,
                   hasItem(hasProperty("aaa",is("a"))));
    }


  以上代码直接通不过编译,具体解决方法参见:
https://weblogs.java.net/blog/johnsmart/archive/2008/04/on_the_subtle_u.html
  也即,以上测试代码必须改成:
    @Test
    public void testNotSeniorQuery() throws Exception {
        List parsedQueryParams = queryParamParser.parse(request);//这儿直接用List
        assertThat(parsedQueryParams, notNullValue());
        assertThat(parsedQueryParams, hasSize(6));
        assertThat((List<Object>)parsedQueryParams,  //这儿将List cast 为List<Object>
                   hasItem(hasProperty("aaa",is("a"))));
    }


   虽然这样可以通过编译了,但是我还有更多类似于以下的断言集合中Bean级联属性的需求:
即ParsedQueryParam类包含了一个QueryParam,QueryParam中拥有paramName及paramValue属性,我希望hamcrest能够支持以下的代码:
    @Test
    public void testNotSeniorQuery() throws Exception {
        List parsedQueryParams = queryParamParser.parse(request);
        assertThat(parsedQueryParams, notNullValue());
        assertThat(parsedQueryParams, hasSize(6));

        assertThat((List<Object>)parsedQueryParams,
                hasItem(hasProperty("queryParam.paramName",is("userId1"))));//失败,无法正确断言!!
    }


   可是这样无法成功运行,报如下错误:
引用

java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
at org.hamcrest.core.IsCollectionContaining.matchesSafely(IsCollectionContaining.java:31)
at org.hamcrest.core.IsCollectionContaining.matchesSafely(IsCollectionContaining.java:14)
at org.hamcrest.TypeSafeDiagnosingMatcher.matches(TypeSafeDiagnosingMatcher.java:55)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:12)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
at com.hsit.euler.eqengine.query.parser.impl.QueryParamParserImplTest.testNotSeniorQuery(QueryParamParserImplTest.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
at org.testng.internal.MethodInvocationHelper$1.runTestMethod(MethodInvocationHelper.java:200)
at org.unitils.UnitilsTestNG.run(UnitilsTestNG.java:103)


   此路不通,我就试着换成如下方式:
    @Test
    public void testNotSeniorQuery() throws Exception {
        List parsedQueryParams = queryParamParser.parse(request);
        assertThat(parsedQueryParams, notNullValue());
        assertThat(parsedQueryParams, hasSize(6));

        assertThat((List<Object>)parsedQueryParams,
                hasItem(hasProperty("queryParam",hasProperty("paramName"))));//这样可以成功断言!

    }

   但是以上断言只是断言属性的存在性,如果我断言属性值,即又歇菜了!
    @Test
    public void testNotSeniorQuery() throws Exception {
        List parsedQueryParams = queryParamParser.parse(request);
        assertThat(parsedQueryParams, notNullValue());
        assertThat(parsedQueryParams, hasSize(6));

        assertThat((List<Object>)parsedQueryParams,
                hasItem(hasProperty("queryParam",hasProperty("paramName",is("userId1")))));//NND 这样不行!

    }


   一直想找一个可以很好对集合中Bean进行存在性断言或Bean属性值断言的框架,发现hamcrest很让人失望啊。不知列位有没有好的建议,非常感谢!
分享到:
评论
4 楼 zhanhb 2015-06-30  
使用jdk8
3 楼 wxx_xinxin 2014-01-26  
如果 hamcest 提供方法不能满足的你的需求,自己实现一个类

写个class 去继承 BaseMatcher 
2 楼 wxx_xinxin 2014-01-26  
assertThat(
(List<User>) users,
IsCollectionContaining.<User> hasItem(allOf(
hasProperty("status", is(0)),
hasProperty("name", equalTo("Steve")))));



我简单做了一个性能的比较 ;

如果判断对象是个结果集
1百万条数据

目标数据在中间靠后的位置
原始的for循环要快7倍左右甚至更多。
1 楼 jinnianshilongnian 2013-12-29  
断言属性值相等性 我这边是可以的啊
        List<User> userlist = new ArrayList<>();
        User user1 = new User();
        user1.setId(1L);
        user1.setName("zhang");

        User user2 = new User();
        user2.setId(2L);
        user2.setName("admin");
        user2.setUser2(user2);

        userlist.add(user1);
        userlist.add(user2);

        assertThat((List<Object>)(List)userlist, hasItem(
                hasProperty("user2", hasProperty("name", is("admin")))
        ));


不过使用spring的BeanWrapper很快就能改造一个 
https://github.com/zhangkaitao/spring4-showcase/tree/master/spring-mvc-test/src/test/java/com/sishuok/matcher

相关推荐

    Hamcrest测试断言SwiftHamcrest.zip

    SwiftHamcrest是一个专门为Swift编程语言设计的开源测试断言库,它是基于著名的Java测试框架Hamcrest的灵感构建的。在软件开发中,测试是保证代码质量、稳定性和可靠性的重要环节,而测试断言则是测试中的核心组成...

    hamcrest-core-1.3.jar

    在Java测试领域,Hamcrest是一个不可或缺的工具,它提供了一套丰富的匹配器(Matcher),使得编写断言(Assertion)更加简洁且易于理解。本文将深入探讨hamcrest-core-1.3.jar这个核心库以及其源码文件hamcrest-core...

    test-hamcrest:Java中的hamcrest断言匹配器库的示例

    hamcrest库Matcher库的简单示例 安装(Maven) 最新版本1,3:2012年7月 &lt;groupId&gt;org.hamcrest &lt;artifactId&gt;hamcrest-all &lt;scope&gt;test &lt;version&gt;1.3 没有依赖 匹配的演示文稿 第一次比赛 String s = "a ...

    hamcrest两个jar包

    Hamcrest是一个流行的Java库,专门用于创建和匹配对象的断言,广泛应用于单元测试框架中。本文将详细讨论`hamcrest`库以及在单元测试中的应用。 标题“hamcrest两个jar包”指的是Hamcrest库中的两个核心组件,即`...

    hamcrest-1.3.zip

    Hamcrest是一个Java库,它提供了匹配对象的框架,主要用于单元测试中断言的编写。标题"hamcrest-1.3.zip"指的是这个库的1.3版本被压缩成一个ZIP文件,其中包含了相关的jar包和文档资料。在本文中,我们将深入探讨...

    junit.jar + hamcrest-core.jar + hamcrest-library.jar

    3. **使用Hamcrest断言**:在测试方法中,通过`assertThat()`方法结合Hamcrest的匹配器进行断言,比如`assertThat(result, equalTo(expected))`来检查结果是否等于预期值。 4. **使用`@Before`和`@After`**:可以...

    hamcrest-core-1.3.ORC2.jar:hamcrest的核心包,使用hamcrest框架必须引入的包

    hamcrest是一个用于匹配对象和表达式,进行断言的库,尤其在单元测试中扮演着不可或缺的角色。这个jar包的引入是使用hamcrest框架的基础,无论是使用Eclipse、IDEA或其他Java开发工具,都需要包含这个库才能充分发挥...

    hamcrest-core-1.3的压缩包,hamcrest-core-1.3.jar包 是一款hamcrest的核心包

    Hamcrest是一个强大的匹配对象的库,它为Java提供了一种优雅的方式来定义和使用断言。本文将详细探讨hamcrest-core-1.3及其在软件开发中的关键作用。 一、hamcrest-core概述 hamcrest-core是Hamcrest框架的基础...

    hamcrest-core-1.3.rc2.jar/hamcrest-library-1.3.rc2.jar

    其核心组件"hamcrest-core-1.3.rc2.jar"包含了基本的匹配器和断言类,而"hamcrest-library-1.3.rc2.jar"则扩展了更多的匹配器,使得测试表达更丰富,更易于理解。 1. **Hamcrest Core**:这是Hamcrest的基础部分,...

    hamcrest-library.rar

    Hamcrest是一个强大的匹配框架,它为Java开发者提供了一套灵活且易于使用的断言库。这个名为"hamcrest-library.rar"的压缩包,包含了hamcrest的核心库——hamcrest-library-1.3.jar,以及一些额外的链接资源。本文将...

    hamcrest-library-1.3和hamcrest-core-1.3.rc2.zip

    然而,为了实现更复杂的断言,JUnit通常需要与其他库结合使用,其中Hamcrest是一个非常重要的辅助工具。"hamcrest-library-1.3和hamcrest-core-1.3.rc2.zip"这个压缩包包含了Hamcrest的两个关键组件,它们对于增强...

    hamcrest的jar包

    hamcrest的核心理念是定义期望值,而不是具体的断言行为,这使得测试代码更加简洁且易于理解。 标题提及的“hamcrest的jar包”是指hamcrest库的可执行文件,通常以`.jar`格式存在,这种文件类型在Java中被称为Java ...

    hamcrest-core-1.3.rc2.jar

    标题中的"hamcrest-core-1.3.rc2.jar"是一个Java库,它是Hamcrest框架的核心组件,主要用于编写可读性高的匹配器(matcher)来断言预期的代码行为。Hamcrest是一个开源项目,其目标是提供一个高质量的、类型安全的、...

    hamcrest1.3完整版

    - **与JUnit集成**: 在JUnit测试中,可以使用`assertThat()`方法结合Hamcrest的`Matcher`进行断言,例如`assertThat(actual, equalTo(expected))`,这比传统的`assertEquals()`更具有可读性。 - **自定义验证**: ...

    hamcrest-core.rar

    在JUnit 4.12版本中,我们发现它依赖于一个名为Hamcrest Core的库,这个库对于编写精确且易于理解的断言至关重要。本文将深入探讨Hamcrest Core的不同版本以及其在JUnit测试中的作用。 首先,让我们了解一下...

    hamcrest-core-1.3.rc2.jar,hamcrest-library-1.3.jar、

    支持Junit测试,简单实用,只需要添加即可,hamcrest-library-1.3.jar包是hamcrest的核心包,这个jar包主要用于补充hamcrest core包中的断言,导入后就可以正常开发使用了,主要适用于eclipse中的JUnit4测试操作,...

    hamcrest-all-1.0.jar.zip包

    在JUnit中,Hamcrest常作为断言库与JUnit结合使用,提供丰富的匹配器(matchers)来验证预期结果。`SelfDescribing`接口是Hamcrest的核心部分,它定义了一个方法`describeTo(Description)`,该方法用于将对象的描述...

    junit+hamcrest集成jar包

    Junit作为Java领域最常用的单元测试框架,而Hamcrest则是一款强大的匹配器库,能为测试提供丰富的断言。本文将详细介绍Junit与Hamcrest的集成,以及如何利用它们进行高效的测试。 一、Junit简介 Junit是Java编程...

Global site tag (gtag.js) - Google Analytics