【问题标题】:How to test method with nested for loops如何使用嵌套的 for 循环测试方法
【发布时间】:2012-09-17 12:20:14
【问题描述】:

我是单元测试的初学者。 我使用 JUnit 和 Mockito。这是我要测试的一种示例方法。

public List<Person> getPeopleList(List<Aggregate<Person>> aggregateList) {
    List<Person> resultList = new ArrayList<Person>();
    for (Aggregate<Person> aggregate : aggregateList) {
        resultList.add(aggregate);

        for (Person person : aggregate) {
            resultList.add(person);
        }
    }
    return resultList; // the result is person and aggregate list
}

我尝试了很多方法,但我都做不好。示例:

@Test
public void getPeopleListTest(){
    ClassUnderTest testedClass = new ClassUnderTest();

    Aggregate aggregate = mock(Aggregate.class);
    Iterator<Aggregate<Person>> aggregateIterator = mock(Iterator.class);
    when(aggregateIterator.hasNext()).thenReturn(true, false);
    when(aggregateIterator.next()).thenReturn(aggregate);

    List<Aggregate<Person>> aggregateList = mock(List.class);

    aggregateList.add(aggregate);

    List<Person> list = testedClass.getPeopleList(aggregateList);

    assertEquals(1, list.size());
}

提前谢谢你。

【问题讨论】:

    标签: java unit-testing junit mocking mockito


    【解决方案1】:

    我不会嘲笑所有可能的事情。我只会模拟您要测试的类并假设 List 行为正确。

    public class Main {
        interface Person {
        }
    
        interface Aggregate<T> extends Person, Iterable<T> {
        }
    
        public static List<Person> getPeopleList(List<Aggregate<Person>> aggregateList) {
            List<Person> resultList = new ArrayList<Person>();
            for (Aggregate<Person> aggregate : aggregateList) {
                resultList.add(aggregate);
    
                for (Person person : aggregate) {
                    resultList.add(person);
                }
            }
            return resultList; // the result is person and aggregate list
        }
    
        public static void main(String... args) {
            Aggregate<Person> aggregate = mock(Aggregate.class);
            Aggregate<Person> aggregate2 = mock(Aggregate.class);
            Person person = mock(Person.class);
            Person person2 = mock(Person.class);
            when(aggregate.iterator()).thenReturn(Arrays.asList(person).iterator());
            when(aggregate2.iterator()).thenReturn(Arrays.asList(person2).iterator());
    
            List<Person> list = getPeopleList(
                    Arrays.asList(aggregate, aggregate2));
            System.out.println(list);
            System.out.println("size: " + list.size());
        }
    }
    

    打印

    [Mock for Aggregate, hashCode: 2037567902, Mock for Person, hashCode: 1629493852, Mock for Aggregate, hashCode: 44220373, Mock for Person, hashCode: 182467149]
    size: 4
    

    【讨论】:

    • 模拟Aggregate&lt;Person&gt;Person 是否有特定原因。在我看来,这没有必要。
    • 这取决于您要测试的内容。如果您想在不假设这些接口的情况下测试该方法,则需要模拟它们。如果你确信他们的行为正确,你就不需要嘲笑任何东西。
    • 感谢您的所有回复。我想为Aggregate&lt;Person&gt;Person 使用模拟。我想我理解这条线:when(aggregate.iterator()).thenReturn(Arrays.asList(person).iterator()); 当调用Aggregate 迭代器时,它返回Person 的迭代器。但是我怎样才能改变聚合和人的数量。我想检查例如两个聚集体和两个人。我不知道该怎么做:|
    • @LancerX 我已经更改了两个 Aggregate 和 Person 的示例。顺便说一句,如果你有超过 2 个,你可以循环构建这些。
    • 我不知道这个解决方案是否正确。当我删除行 when(aggregate...when(aggregate2... 时,测试仍然通过。除此之外,getPeopleList应该返回包含四个元素(聚合、聚合2、人员、人员2)而不是两个的列表。
    【解决方案2】:

    您需要问自己要测试的是什么?在示例函数中,您要检查当函数被赋予聚合列表时,它返回聚合和人员的混合扁平列表。

    所以,我不会模拟 List,而是检查结果列表是否包含所有预期的项目:

    Aggregate aggregate = new Aggregate(...);
    //add persons to aggregate.
    
    List<Aggregate<Person>> aggregateList = new ArrayList();
    aggregateList.add(aggregate);
    
    List<Person> list = testedClass.getPeopleList(aggregateList);
    assertEquals(Collections.singletonList(aggregate), result);
    

    否则,如果您更改迭代参数 List 中所有项目的方式,则需要更新测试。

    你可以测试的另一件事:

    1. 作为参数给出的列表未修改。
    2. 函数检查 null 参数。

      Preconditions.checkNotNull(aggregateList, "AggregateList cannot be null");
      
    3. 空参数导致空结果。

    【讨论】:

      猜你喜欢
      • 2021-12-11
      • 2018-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多