我在理解单元测试方面取得了一些进展,但是对于我尝试测试的每一种方法,都有新的问题:
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 Session 中读取数据以确定当前项目,并OptionQuery
从数据库中读取数据。所以我目前的理解是,我必须创建一个夹具来设置一个聚合、一个测试数据库和一个为我的会话对象返回某些内容的模拟。这是正确的,如果是这样,我为什么要花这么多精力来测试一种方法?
编辑同时,我重构了该handle
方法以使其更具可测试性:
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()
);
}
但我觉得现在的担忧已经分开了一点。