Как вы должны написать тестовые примеры для нескольких реализаций одного и того же интерфейса? - PullRequest
2 голосов
/ 09 января 2009

Прежде чем задать вопрос, позвольте мне объяснить текущую настройку:

У меня есть сервисный интерфейс, скажем, Service, и одна реализация, скажем, ServiceImpl. Этот ServiceImpl использует некоторые другие сервисы. Все услуги загружаются как бобовые к весне.

Теперь я хочу написать тестовые случаи junit для ServiceImpl. Для этого я использую applicationContext, чтобы получить компонент Service, а затем вызываю различные методы для его проверки.

Все выглядит нормально для открытых методов, но как мне написать контрольные примеры для частных методов? Потому что у нас не может быть одинаковых приватных методов для разных реализаций?

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

Ответы [ 4 ]

5 голосов
/ 09 января 2009

Пуристический ответ таков: частные методы называются так по причине! ; -)

Переверните вопрос: учитывая только спецификацию (общедоступного) интерфейса, как бы вы изложили свой план тестирования перед написанием кода? Этот интерфейс описывает ожидаемое поведение объекта, который его реализует; если на этом уровне это невозможно проверить, значит, с дизайном что-то не так.

Например, если мы транспортная компания, у нас могут быть следующие (псевдокодированные) интерфейсы:

CapitalAsset {
    Money getPurchaseCost();
    Money getCurrentValue();
    Date  whenPurchased();
    ...
}

PeopleMover {
    Weight getVehicleWeight();
    int    getPersonCapacitly();
    int    getMilesOnFullTank();
    Money  getCostPerPersonMileFullyLoaded(Money fuelPerGallon);
    ...
}

и может иметь классы, в том числе:

Bus implements CapitalAsset, PeopleMover {
    Account getCurrentAdvertiser() {...}
    boolean getArticulated() {...}
    ...
}

Computer implements CapitalAsset {
    boolean isRacked() {...}
    ...
}

Van implements CapitalAsset, PeopleMover {
    boolean getWheelchairEnabled() {...}
    ...
}

При разработке концепции и интерфейса CapitalAsset мы должны были договориться с финансовыми парнями о том, как должен любой экземпляр CapitalAsset вести себя. Мы бы написали тесты против CapitalAsset, которые зависят только от от этого соглашения; мы должны иметь возможность выполнять эти тесты на Bus, Computer и Van, независимо от того, какой конкретный класс был задействован. Аналогично для PeopleMover.

Если нам нужно проверить что-то о Bus, которое не зависит от генерального контракта для CapitalAsset и PeopleMover, тогда нам нужны отдельные тесты шины.

Если конкретный конкретный класс имеет публичные методы, которые настолько сложны, что TDD и / или BDD не могут точно выразить их ожидаемое поведение, то, опять же, это признак того, что что-то не так. Если в конкретном классе есть частные «вспомогательные» методы, они должны быть там по определенной причине; должна быть возможность задать вопрос «Если бы у этого помощника был дефект, какое общественное поведение было бы затронуто (и как)?»

Для законной, присущей сложности (т. Е. Происходящей из проблемной области) может быть целесообразным, чтобы класс имел частные экземпляры вспомогательных классов , которые берут на себя ответственность за конкретные концепции. В этом случае вспомогательный класс должен быть тестируемым сам по себе.

Хорошее эмпирическое правило:

Если это слишком сложно для тестирования, это слишком сложно!

4 голосов
/ 09 января 2009

Приватные методы должны осуществляться через открытый интерфейс класса. Если у вас есть несколько реализаций одного и того же интерфейса, я бы написал тестовые классы для каждой реализации.

0 голосов
/ 09 января 2009

Я нашел интересную статью о том, как тестировать частные методы с помощью JUNIT на http://www.artima.com/suiterunner/privateP.html

Итак, я предполагаю, что мы должны предпочесть косвенное тестирование частных методов путем тестирования открытых методов. Только в исключительных случаях нам следует подумать о тестировании частных методов.

0 голосов
/ 09 января 2009

Я думаю, вам следует разбить тестовые случаи.

Сначала вы тестируете класс, который вызывает различные реализации интерфейсов. Это будет означать, что вы тестируете общедоступные методы.

После этого вы тестируете классы реализации интерфейса в другом тестовом примере. Их можно назвать методом с отражением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...