Этот обработчик команд тестируемый? - PullRequest
0 голосов
/ 07 декабря 2018

Я добился некоторого прогресса в понимании модульного тестирования, но с каждым методом, который я пытаюсь протестировать, возникают новые вопросы:

public function handle( SendNotification $command ) {

    $DTO = $this->Assembler->build();

    $subject = sprintf(
        $command->getFirstName(),
        $command->getLastName()
    );

    $EmailComponents = new EmailComponents(
        $subject,
        $DTO->getProject()->getSettings()->getValueOf( 'recipient' ),
        $this->OptionQuery->getOption( 'business_email' ),
        $this->NotificationRenderFactory->render( 'template' ) )
    );

    $this->Mailer->send( $EmailComponents );

}

$DTO - это в основном агрегированный кластер, в котором «проект» являетсясовокупный корень.Он читает данные из сеанса PHP для определения текущего проекта, а OptionQuery читает данные из базы данных.Таким образом, мое текущее понимание состоит в том, что мне нужно создать приспособление, которое устанавливает аггреат, тестовую базу данных и макет, который возвращает что-то для моего объекта сеанса.Это правильно, и если да, то почему я хотел бы приложить столько усилий для тестирования одного метода?

РЕДАКТИРОВАТЬ Тем временем я реорганизовал метод handle, чтобы сделать его болееtestable:

public function handle( SendNotification $command ) {

    $EmailComponents = $this->EmailComponentsAssembler->build( $command );

    $this->Mailer->setup( $EmailComponents );

    $this->Mailer->send();

}

Метод ассемблера build (который на самом деле скорее заводской) все еще довольно уродлив:

public function build( SendNotification $command ): EmailComponentsDTO {

    $request = Request::createFromGlobals();

    $Recipient = $this->ProjectRecipientEmailQuery->execute( $request->request->get( 'destination' ) );

    if ( !\is_email( $Recipient ) ) :

        throw new \Exception( 'No email address found!' );

    endif;

    return new EmailComponentsDTO(
        TRUE,
        $Recipient,
        (array)$command->getCustomField( 'additional_recipients' ),
        $this->OptionQuery->getOption( 'email_from' ),
        $this->OptionQuery->getOption( 'email_email' ),
        (string)$this->NotificationSubject->render( $command ),
        (string)$this->NotificationRenderFactory->render( 'EmailNotification', $command ),
        $command->getPriority()
    );
}

Но я чувствую, что проблемы сейчасотделился немного лучше.

1 Ответ

0 голосов
/ 05 февраля 2019

Модульное тестирование предназначено для поиска ошибок в изолированном коде.Но в вашем коде преобладают взаимодействия, например, с Assembler, Mailer, EmailComponents и т. Д. Ошибки в этой части кода будут связаны с взаимодействиями с другими частями программного обеспечения: вы вызываете нужные функции вправильный порядок с аргументами в правильном порядке с аргументами, имеющими правильный вид содержания?Тестирование с помощью имитаторов не ответит вам на следующие вопросы: Если вы неправильно поняли, как вызывать библиотеку, реализованные вами макеты будут отражать ваши собственные заблуждения.Вместо этого вы должны протестировать такой код с помощью интеграционного тестирования.

Единственный там алгоритмический код:

$subject = sprintf(
    $command->getFirstName(),
    $command->getLastName()
);

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

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

...