Как проверить количество вызовов приватных методов в конструкторе?

У меня есть следующий класс:

public class LegacyClass()
{
    public LegacyClass(final int aModeOfOperation)
    {
        if (aModeOfOperation == 0)
        {
            addSomeValues();
            addSomeValues();
        }
        else if (aModeOfOperation == 1)
        {
            addSomeValues();
        }
    }

    private void addSomeValues()
    {
    }
}

Я хочу написать модульный тест, который бы проверял, что

  1. вызов LegacyClass(0) приводит к тому, что частный метод addSomeValues вызывается 2 раза и
  2. вызов LegacyClass(1) вызывает однократный вызов закрытого метода addSomeValues.

Я знаю, что можно использовать объекты-шпионы в Mockito/PowerMockito для подсчета количества вызовов частных методов, но, насколько я знаю, эти подходы работают, только если рассматриваемые методы вызываются после построения тестируемого класса. .

Можно ли написать модульный тест, описанный выше, без изменения конструктора LegacyClass?


person Mentiflectax    schedule 27.11.2013    source источник
comment
Если вы тестируете приватные методы, то часто вы можете тестировать не то, что нужно. Можете ли вы проверить результат того, что происходит, когда addSomeValues() вызывается дважды? Тестирование «черного ящика» › тестирование «белого ящика» даже на уровне класса.   -  person vikingsteve    schedule 28.11.2013
comment
@vikingsteve Тестирование результатов - это решение, которое я использую сейчас, потому что я не смог найти ничего лучше.   -  person Mentiflectax    schedule 28.11.2013
comment
Отлично, я думаю, вы действительно нашли лучшее решение. Если кто-то когда-нибудь рефакторит LegacyClass, ваши тесты все равно будут работать зеленым цветом!   -  person vikingsteve    schedule 28.11.2013


Ответы (2)


Я думаю, что вы получите гораздо больше пользы от модульного тестирования, если сможете выполнять тестирование на основе состояния (http://blog.jayfields.com/2008/02/state-based-testing.html?m=1) о требованиях/поведении общедоступных методов, а не о тестировании числа вызова приватных методов. Это может быть возможно в некоторых изолированных фреймворках, но с точки зрения модульного тестирования я не вижу большой ценности.

Подумайте о каком-то модульном тесте, вы бы проверили, что метод был вызван, или метод был вызван x номеров, если раз. Эти тесты являются проверочными, и они все еще действительны. НО ключевым фактором является то, что большинство фреймворков фиктивных объектов позволяют вам выполнять эти проверки против общедоступных методов (по крайней мере, в .net). Причина в том, что частные методы не очень важны с точки зрения модульного тестирования, потому что они являются деталями внутренней реализации. Старайтесь избегать сбоев при тестировании для изменения схемы кода.

person Spock    schedule 27.11.2013

Я не думаю, что это возможно с помощью mockito, так как вы объявляете шпиона таким образом spy(new LegacyClass()), поэтому ваш конструктор вызывается до того, как объект будет шпионить. Может быть, есть способ с PoweverMock, но я обычно не одобряю использование PowerMock, потому что не прилагаются усилия для рефакторинга кода для правильного дизайна.

Вместо этого я настоятельно рекомендую вам реорганизовать ваш старый код, сделав его более пригодным для тестирования (ключевой здесь является разработка через тестирование).

Если вам абсолютно необходимо сохранить этот устаревший код с совместимыми изменениями, но без PowerMock ; Вместо этого я бы сначала увеличил уровень видимости до package visible :

private void addSomeValues() { ... }

Затем напишите статический подкласс LegacyClass в своем тесте и переопределите метод addSomeValues, который увеличит счетчик вызова super.

public class LegacyCodeTest {
  ...

  static class AddSomeValuesCounteringLegacyClass extends LegacyClass {
    public int counter;
    void addSomeValues() { counter = counter + 1; super.addSomeValues(); }
  }
}

Затем в своем тесте вы насыщаете этот класс и утверждаете количество вызовов;

person Brice    schedule 27.11.2013