Класс модульного тестирования, который не имеет вывода - PullRequest
3 голосов
/ 20 июля 2010

Часто класс не имеет прямого вывода; он манипулирует своими зависимостями, заставляя их что-то делать.

Например:

internal interface IEmailer
{
    void SendEmail();
}

class ReportSender
{
    public IEmailer Emailer { get; set; }

    public ReportSender(IEmailer emailerToUse)
    {
        Emailer = emailerToUse;
    }

    public void SendReport()
    {
        // Do whatever is needed to create the report

        Emailer.SendEmail();
    }
}

Создание макета IEmailer и заставить его ожидать, что IEmailer.SendEmail (), кажется, выставляет слишком много внутренностей класса и делает тест хрупким. Но я не могу придумать другого способа проверить этот класс.

Как написать модульные тесты для такого класса?

Ответы [ 6 ]

3 голосов
/ 20 июля 2010

Создание насмешки над IEmailer само по себе не раскрывает слишком много класса. Скорее, он делает его открытым для расширения .

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

Голливудский принцип может быть очень полезен здесь, потому что, если ваши зависимости в основном разработаны вокруг void методов, динамические mock, такие как Moq или Rhino Mocks, как правило, просто игнорируют вызовы методов, если вы специально не скажете им заботиться о конкретном.

2 голосов
/ 20 июля 2010

Использование объектов Mock - правильный способ написания модульного теста для этого метода. Вы не хотите, чтобы ваш тест отправлял письмо по электронной почте. Ложные объекты позволяют разбивать зависимости между различными классами для целей модульного тестирования.

Вот пример использования Rhino Mocks.

http://www.ayende.com/projects/rhino-mocks.aspx

IEmailer emailer = MockRepository.GenerateMock<IEmailer>();
emailer.Expect(x => x.SendEmail());

ReportSender reportSender = new ReportSender();
reportSender.Emailer = emailer;
reportSender.SendReport();

emailer.VerifyAllExpectations();
1 голос
/ 20 июля 2010

Создание макета IEmailer и заставить его ожидать IEmailer.SendEmail ()

это именно то, как вы бы это проверили.

, так как это тесты UNIT, вы не подвергаете слишком много. предполагается, что вы выполняете все функции тестируемого устройства, и это нормально, если вы обладаете внутренними знаниями об устройстве.

0 голосов
/ 20 июля 2010

Создаем макет IEmailer и заставляем его ожидать, что IEmailer.SendEmail (), по-видимому, раскрывает слишком много внутренностей класса и делает тест хрупким.

Тогда почему вы выставляете публичную собственность, требующую внутреннего интерфейса?

Сделайте интерфейс открытым и ваши реализации будут внутренними.

0 голосов
/ 20 июля 2010

Создание фиктивного IEmailer и ожидание вызова SendEmail - правильный способ проверить этот сценарий.

0 голосов
/ 20 июля 2010

Я пока не очень разбираюсь в модульном тестировании, так что это может быть не слишком полезно ... но мне кажется, ваше предложение вычеркнуть зависимость находится на правильном пути. Затем вы можете проверить состояние максифицированных зависимостей после завершения операции, чтобы определить, выполнял ли IEmailer ожидаемые манипуляции с ними?

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