1

我在 mongo 中有需要验证的数据:

"items" : [
            {
                    "item" : 0,
            },
            {
                    "item" : 1,
            }
    ],

我的代码中有一个 for 循环:

for (Object a : getItems()){
 HashMap<?, ?> b = (HashMap<?, ?>)a;
 assertTrue(b.containsValue(0));
}

这里有一个问题,因为 items 的值为 1 和 0,如果它也包含 1,我需要为第二次迭代断言。如何验证 1 和 0 是否都存在?

有没有其他的断言方法可以做到这一点?

编辑:

List lt1 = new ArrayList();
lt1.add(0);
lt1.add(1);
List lt2 = new ArrayList();

for (Object a : getItems()){
 HashMap b = (HashMap)a;
 lt2.add(b.get("item");
}

assertThat(lt2, hasItems(lt1));

这会在 assertThat.. 行引发调用目标异常。此外,JUNIT 显示一个断言错误,如下所示:

Expected : A collection of [0,1]
Got : [0,1]
4

2 回答 2

2

由于您使用的是 JUnit,v4.4 开始,该库可以使用hamcrest匹配器库,该库提供了丰富的 DSL 来构建测试表达式。这意味着您可以完全删除循环并编写单个断言,测试所有预期值的存在。

例如,hamcrest 有一个内置功能hasItems()(v1.3.RC2 的文档链接,但 v1.3 已发布 - 抱歉找不到最新链接)。

import java.util.List;
import java.util.Arrays;
import static org.hamcrest.Matchers.hasItems;
import static org.junit.Assert.assertThat;

@Test
public void bothValuesShouldBePresent() {
    List<Integer> itemValues = Arrays.asList(new Integer[]{ 0, 1, 2, 3 });
    Integer[] expected = { 0, 1 };
    assertThat(itemValues, hasItems(expected));
}

当然,这假设您可以修改您的getItems()方法以返回一个简单的List<Integer>.

最后,根据您使用的 JUnit 版本,hamcrest 可能捆绑也可能不捆绑。JUnit 在 v4.4 和 v4.10 之间内联 hamcrest-core。因为它只是hamcrest-core,所以我在我的项目中明确添加了hamcrest-all依赖项。从 JUnit v4.11 起,hamcrest 不再内联(恕我直言),因此如果您想使用匹配器,您将始终需要显式添加依赖项。

此外,这是一篇关于 hamcrest 集合匹配的有用博客文章。

编辑:

我试图考虑你getItems()可能会返回什么,这是一个更新的测试示例。请注意,您需要将预期值转换为数组 - 请参阅为什么尝试使用 Hamcrest 的 hasItems 的代码无法编译?

@Test
public void bothValuesShouldBePresent() {
    List lt1 = new ArrayList();
    lt1.add(0);
    lt1.add(1);
    List lt2 = new ArrayList();

    List fakeGetItems = new ArrayList() {{ add(new HashMap<String, Integer>() {{ put("item", 0); }}); add(new HashMap<String, Integer>() {{ put("item", 1); }} ); }};

    for (Object a : fakeGetItems) {
     HashMap b = (HashMap)a;
     lt2.add(b.get("item"));
    }

    assertThat(lt2, hasItems(lt1.toArray(new Integer[lt1.size()])));
}
于 2013-01-03T09:03:28.157 回答
0

使用AssertJ更容易

@Test
public void bothValuesShouldBePresent1()  {
  List<Integer> lt2 = Arrays.asList(0, 1);
  List<Integer> lt1 = Arrays.asList(0, 1);
  assertThat(lt2).containsExactlyElementsOf(lt1);
}

@Test
public void bothValuesShouldBePresent2()  {
  List<Integer> lt2 = Arrays.asList(0, 1);
  assertThat(lt2).containsExactly(0, 1);
}

@Test
public void bothValuesShouldBePresent3()  {
  List<MyItem> lt2 = Arrays.asList(new MyItem(0), new MyItem(1));
  assertThat(extractProperty("item").from(lt2))
      .containsExactly(0, 1);
}
于 2013-12-20T20:55:40.533 回答