假设我指定了这个类(遵循BDD方法)
class Logger
{
private $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function logMessageAsRead(Message $message)
{
$log = new LoggedMessage($message);
$this->em->persist($message);
}
}
和LoggedMessage
定义如下
class LoggedMessage
{
private $date;
private $message;
public function __construct(Message $message)
{
$this->date = new DateTime();
$this->message = $message;
}
}
有时我的规范示例失败,因为规范中实例化的Message
日期与Logger
类中的日期不一致。
class LoggerSpec
{
public function it_logs_a_message(Message $message, EntityManager $em)
{
$log = new LoggedMessage($message);
$em->persist($log)->shouldBeCalled(1);
$this->logMessageAsRead($message);
}
}
第一个问题:我的代码中有异味吗?所以我需要创建一个合作者吗?(一个工厂),并注入到Logger
,以创建一个新的LoggedMessage
?
第二个问题:如果没有必要注入新的合作者,我如何确保我的规范每次都能正常工作,而不会因为日期和时间的差异而随机失败?
-
LoggedMessage
s的注入工厂将是一个很好的解决方案,特别是如果您不想在修改时关闭LoggedMessage
的构造函数。一般来说,最好将创建对象的关注点与使用对象的关注点分开。 -
最简单的解决方案是检查特定类型而不是具体实例:
em ->保存(参数::类型(LoggedMessage::类))-> shouldBeCalled (1),
如果您希望您的期望更具体,您可以使用Argument::which
或Argument::that
:
$em->persist(Argument::which('getMessage', $message))->shouldBeCalled(1);
$em->persist(Argument::that(function($arg) {
return $arg->getDate() instanceof DateTime;
}))->shouldBeCalled(1);