我怎样才能JUnit测试" printlist"?

时间:2014-09-27 22:45:56

标签: java testing 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的实用程序类,它是一个数组列表。

3 个答案:

答案 0 :(得分:0)

嗯......想想这种方法的合同:它有什么承诺?它承诺打印一个整数列表,用逗号分隔,并在括号内。因此,您可以在单元测试中指定它。

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

使用您希望打印的字符串为某些列表编写一个夹具。不要忘记角落的情况:一个空列表。然后,可能是大小为1的列表,大小为10的列表。

要查看已打印的内容,您可以通过调用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只允许您忽略您不关心的所有方法(即,您不需要实现整个PrintStream接口)

关于重复存根的一个小旁注:我们需要存根两个方法printprintln,因为两者都被使用了。此外,由于覆盖,print(String x)print(Object x)不同,因此我们需要将它们都存在。

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

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