【问题标题】:Junit: assert that a list contains at least one property that matches some conditionJunit:断言一个列表至少包含一个匹配某个条件的属性
【发布时间】:2018-10-08 01:15:38
【问题描述】:

我有一个方法可以返回MyClass 类型的对象列表。 MyClass 有很多属性,但我关心的是typecount。我想编写一个测试,断言返回的列表至少包含一个与特定条件匹配的元素。例如,我想要"Foo" 类型列表中的至少一个元素并计数1

我试图弄清楚如何做到这一点,而不是逐字逐句遍历返回的列表并单独检查每个元素,如果我找到一个通过了就中断,例如:

    boolean passes = false;
    for (MyClass obj:objects){
        if (obj.getName() == "Foo" && obj.getCount() == 1){
            passes = true;
        }
    }
    assertTrue(passes);

我真的不喜欢这种结构。我想知道使用 assertThat 和一些 Matcher 是否有更好的方法。

【问题讨论】:

    标签: java unit-testing junit hamcrest


    【解决方案1】:

    使用 hamcrest 进口

    import static org.hamcrest.Matchers.allOf;
    import static org.hamcrest.Matchers.hasItem;
    import static org.hamcrest.Matchers.hasProperty;
    import static org.hamcrest.Matchers.is;
    import static org.junit.Assert.assertThat;
    

    你可以测试

        assertThat(foos, hasItem(allOf(
            hasProperty("name", is("foo")),
            hasProperty("count", is(1))
        )));
    

    【讨论】:

    • 这会断言至少一个项目同时具有这两个属性,还是至少有一个项目具有每个属性? IE。这是否确保它是具有两者的同一项目?
    • 检查列表中至少有 1 项 name=="foo" 并且相同的项目有 count==1
    • 我的 IDE 似乎找不到 org.hamcrest.Matchers。我需要什么 Maven 存储库?我以为是this,但不是
    • 我确实在使用v1.3
    【解决方案2】:
    assertTrue(objects.stream().anyMatch(obj ->
        obj.getName() == "Foo" && obj.getCount() == 1
    ));
    

    或者更有可能:

    assertTrue(objects.stream().anyMatch(obj ->
        obj.getName().equals("Foo") && obj.getCount() == 1
    ));
    

    【讨论】:

      【解决方案3】:

      我不知道是否值得为此使用 Hamcrest,但很高兴知道它就在那里。

      public class TestClass {
          String name;
          int count;
      
          public TestClass(String name, int count) {
              this.name = name;
              this.count = count;
          }
      
          public String getName() {
              return name;
          }
      
          public int getCount() {
              return count;
          }
      }
      
      @org.junit.Test
      public void testApp() {
          List<TestClass> moo = new ArrayList<>();
          moo.add(new TestClass("test", 1));
          moo.add(new TestClass("test2", 2));
      
          MatcherAssert.assertThat(moo,
                  Matchers.hasItem(Matchers.both(Matchers.<TestClass>hasProperty("name", Matchers.is("test")))
                          .and(Matchers.<TestClass>hasProperty("count", Matchers.is(1)))));
      }
      

      【讨论】:

        猜你喜欢
        • 2017-12-29
        • 1970-01-01
        • 2022-01-13
        • 1970-01-01
        • 2018-08-24
        • 2019-11-09
        • 2022-01-13
        • 2017-04-30
        • 2020-12-28
        相关资源
        最近更新 更多