Как я могу тестировать «список печати»?

1

Я довольно долго смотрел на этот код, и я действительно не могу понять, как и что делать для его тестирования 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
    мои извинения, добрый сэр.
Теги:
testing
junit

3 ответа

0
Лучший ответ

Ну... подумайте о контрактах этого метода: что это обещает? Он обещает напечатать список целых чисел, разделенных запятой и внутри скобок. Таким образом, вы можете указать это в модульном тесте.

Edit2: На всякий случай, если вам понравится модульное тестирование, будет ли список напечатан в порядке: я бы не считал это свойством метода 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);
}

Обратите внимание, что вы, вероятно, захотите извлечь setup- и часть разрыва, чтобы использовать ее в других тестах и сделать ваш тест доступным для чтения. Если я не ошибаюсь, JUnit предоставляет функциональность для добавления кода, который вызывается до и после каждого выполнения теста, если вы укажете его с помощью @Before и @After аннотации.

Очевидно, вам не обязательно нужно Mockito для достижения этого. Вы также можете написать класс, который реализует PrintStream и сохраняет печатные строки. В этом случае Mockito просто позволяет игнорировать все методы, которые вам не нужны (т. PrintStream Вам не нужно реализовывать весь интерфейс PrintStream)

Небольшой пояс по дублированию заглушки: нам нужно заглушить оба метода, print и println, потому что оба используются. Кроме того, из-за переопределения print(String x) не совпадает с print(Object x), поэтому нам нужно их заглушить.

  • 0
    не могли бы вы привести пример? благодарю вас
  • 0
    Конечно. Я создам пример и отредактирую его в своем ответе
Показать ещё 5 комментариев
0

В системных правилах библиотеки есть правило JUnit, называемое StandardOutputStreamLog. С помощью этого правила вы можете протестировать свой код, который записывается в 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());
    }
}
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]"));
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню