2014-09-27 89 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()); 
    } 
}