簡體   English   中英

JUnit如何測試“打印列表”?

[英]How can I JUnit test “printlist”?

我已經盯着這段代碼已經有一段時間了,我真的不知道如何以及如何對其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的實用程序類,它是一個數組列表。

好吧...考慮這種方法的合同:它能保證什么? 它承諾將打印一個由逗號分隔並放在方括號內的整數列表。 因此,您可以在單元測試中指定它。

Edit2:以防萬一您想測試一下是否按順序打印列表:我不會認為這是printList方法的屬性。 應該在修改OrderedIntList的方法中測試此屬性。

用您希望打印的字符串為某些列表編寫一個燈具。 不要忘了極端情況:一個空列表。 然后,可能是大小為1的列表和大小為10的一個列表。

要檢查已打印的內容,可以創建一個新的PrintStream ,並通過調用System.setOut設置System.out的值。 在每次測試開始時都要執行此操作,並且不要忘記重置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);
}

請注意,您可能想要提取setup-和拆解部分,以將其用於其他測試中並使測試可讀。 如果我沒有記錯的話,如果您使用@Before@After注釋指定它,那么JUnit將提供添加在每次測試執行之前和之后調用的代碼的功能。

顯然,您不一定需要Mockito來實現此目的。 您還可以編寫一個實現PrintStream並存儲打印字符串的類。 在這種情況下,Mockito僅允許您忽略所有不需要的方法(即,您不需要實現整個PrintStream接口)

關於存根重復的小注釋:我們需要對兩個方法都進行存根,因為printprintln都被使用了。 另外,由於覆蓋, print(String x)print(Object x) ,因此我們需要將它們都存根。

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

系統規則具有一個稱為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());
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM