如何在for循环中为两个不同的值断言true?

时间:2013-01-03 08:20:59

标签: java mongodb junit assert

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

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

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

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

这里有一个问题,因为项目的值为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 ..行引发一个Invocation Target Exception。 此外,JUNIT显示断言错误,如下所示:

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

2 个答案:

答案 0 :(得分:2)

由于您使用的是JUnit,as of 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集合的useful blog post

修改

我试过想一下你的getItems()可能会返回什么,这是一个更新的测试示例。请注意,您需要将期望的值转换为数组 - 请参阅Why doesn't this code attempting to use Hamcrest's hasItems compile?

@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()])));
}

答案 1 :(得分: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);
}