我做了理解单元测试的一些进展,但与每一个方法我尝试测试,也有新的问题:
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
从数据库中读取数据。所以我目前的理解是,我将不得不创建一个夹具,设置了两个一aggreate,测试数据库和返回的东西为我的会话对象进行模拟。那是正确的,如果是这样,我为什么要放那么多的精力投入到测试单个方法?
编辑我的同时,我重构了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()
);
}
但我觉得现在担忧分隔好一点。
单元测试是在孤立的代码中发现的bug。但是你的代码是由占主导地位的互动,例如与Assembler
,Mailer
,EmailComponents
等。在这部分代码,虫子会处于与其他软件部分的相互作用:你叫与参数的正确的顺序正确的功能与具有正确的内容类型的参数的正确的顺序?与嘲笑测试不会回答你这些问题:如果你误会了如何调用库,实现嘲笑会反映自己的误解。相反,你应该测试这样的代码集成测试。
在那里唯一的算法代码是:
$subject = sprintf(
$command->getFirstName(),
$command->getLastName()
);
它甚至看起来我错了,因为我希望一些格式字符串是第一个参数sprintf
(但我不熟悉PHP)。如果我是对这个是一个错误,这是严格来说,还集成bug,但一个你可以与单元测试发现,自从你就懒得存根sprintf
。
因此,对于您的测试问题的可能解决方案可以提取主题字符串创建成一个小的辅助功能,并测试一个与单元测试,但与集成测试测试的其他的功能。