2014-09-27 60 views
1

我一直在盯着这段代码已经有相当长的一段时间了,我真的无法弄清楚如何以及如何为其JUnit测试做些什么。JUnit如何测试“打印列表”?

static void printList(OrderedIntList list) { 
    System.out.print("["); 
    for (int i = 0; i < list.orderedIntegerList.length; i++) { 
     System.out.print(list.orderedIntegerList[i]); 
     if (i != list.orderedIntegerList.length - 1) { 
      System.out.print(", "); 
     } 
    } 
    System.out.println("]"); 
} 

此代码来自名为orderedIntList的实用程序类,它是一个数组列表。

+0

我的歉意,善良的先生。 – 2014-09-28 01:29:38

回答

0

那么......想想这个方法的契约:它承诺什么?它承诺打印一个整数列表,用逗号分隔,并在括号内。所以,你可以在单元测试中指定它。

编辑2:以防万一你想看单元测试列表是否按顺序打印:我不会认为这是printList方法的属性。应该在修改OrderedIntList的方法中测试此属性。

使用您希望打印的字符串为某些列表编写夹具。不要忘记角落案例:一个空的列表。然后,也许和大小10的一个

大小为1的列表要检查哪些已被打印,你可以创建一个新的PrintStream,并设置System.out值,通过调用System.setOut。在每次测试开始时都要这样做,并且不要忘记重置System.out(所以不要忘记存储其原始值)。您使用的PrintStream无需花哨:您只需要能够比较打印的流。您可能需要考虑使用Mockito

编辑:

例如,下面的代码测试是否含有唯一的元素4列表,实际打印字符串"[4]\n"

@Test 
public void aListOfSizeOneShouldPrintTheElementWithinBrackets() { 
    /* Setup */ 
    final StringBuffer printStream = new StringBuffer(); 
    PrintStream mockedOut = mock(PrintStream.class); 
    Mockito.doAnswer(new Answer() { 
     @Override 
     public Object answer(InvocationOnMock invocation) throws Throwable { 
      printStream.append(invocation.getArguments()[0].toString()); 
      return null; 
     } 
    }).when(mockedOut).print(any()); 
    Mockito.doAnswer(new Answer() { 
     @Override 
     public Object answer(InvocationOnMock invocation) throws Throwable { 
      printStream.append(invocation.getArguments()[0].toString()); 
      return null; 
     } 
    }).when(mockedOut).print(anyString()); 
    Mockito.doAnswer(new Answer() { 
     @Override 
     public Object answer(InvocationOnMock invocation) throws Throwable { 
      printStream.append(invocation.getArguments()[0].toString()).append("\n"); 
      return null; 
     } 
    }).when(mockedOut).println(any()); 
    Mockito.doAnswer(new Answer() { 
     @Override 
     public Object answer(InvocationOnMock invocation) throws Throwable { 
      printStream.append(invocation.getArguments()[0].toString()).append("\n"); 
      return null; 
     } 
    }).when(mockedOut).println(anyString()); 
    PrintStream originalOut = System.out; 
    System.setOut(mockedOut); 
    /* the actual test */ 
    ArrayList<Integer> listWithOneElement = new ArrayList<Integer>(); 
    listWithOneElement.add(4); 
    OrderedIntList list = new OrderedIntList(listWithOneElement); 
    OrderedIntList.printList(list); 
    MatcherAssert.assertThat(printStream.toString(), is("[4]\n")); 
    /* Teardown - reset System.out */ 
    System.setOut(originalOut); 
} 

请注意,你可能要解压缩安装 - 和拆解部分在其他测试中使用它,并使您的测试可读。如果我没有弄错,JUnit提供了添加代码的功能,如果您使用@Before@After注释指定它,则在每次测试执行前后都会调用代码。

显然,你不一定需要Mockito来实现这一点。您也可以编写一个实现PrintStream的类并存储打印的字符串。在这种情况下,Mockito只允许您忽略所有您不关心的方法(即,您不需要实现整个接口)

重复存根的一个小旁注:我们需要存根两种方法,printprintln,因为都使用。另外,由于重写,print(String x)print(Object x)不一样,所以我们需要将它们两者都存根。

+0

你能否提供一个例子?谢谢 – 2014-09-27 23:03:29

+0

当然。我会创建一个例子,并将其编辑到我的回答 – 2014-09-27 23:04:44

+0

非常赞赏,队友。 – 2014-09-27 23:07:27

0

@Kulu Limpa答案是正确的,但比实际实施复杂得多,因为你需要一些嘲弄。

,如果你重构代码以

static void printList(OrderedIntList list) { 
    System.out.println(toString(list)); 
} 

static String toString(OrderedIntList list) { 
    StringBuilder result = new StringBuilder(); 
    System.out.println(toString(list)); 
    result.append("["); 
    for (int i = 0; i < list.orderedIntegerList.length; i++) { 
     result.append(list.orderedIntegerList[i]); 
     if (i != list.orderedIntegerList.length - 1) { 
      result.append(", "); 
     } 
    } 
    result.append("]"); 
    return result.toString(); 
} 

测试要容易得多:

@Test 
public void aListOfSizeOneShouldPrintTheElementWithinBrackets() { 
    ArrayList<Integer> listWithOneElement = new ArrayList<Integer>(); 
    listWithOneElement.add(4); 
    OrderedIntList list = new OrderedIntList(listWithOneElement); 

    String result = OrderedIntList.toString(list); 
    MatcherAssert.assertThat(result, is("[4]")); 
} 
0

图书馆System Rules有一个名为StandardOutputStreamLog JUnit的规则。有了这个规则,你可以测试你的代码,写入System.out

public void MyTest { 
    @Rule 
    public final StandardOutputStreamLog log = new StandardOutputStreamLog(); 

    @Test 
    public void test() { 
     OrderedIntList list = ... 
     printList(list); 
     assertEquals("[1,2,3,4]", log.getLog()); 
    } 
}