Определение класса, который создает экземпляр чего-либо

Допустим, у меня есть этот класс, который я задавал (следуя 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?

Вопрос номер два: если нет необходимости вводить нового соавтора, как я могу быть уверен, что моя спецификация работает каждый раз и не выходит из строя случайным образом из-за несоответствия даты и времени?

1

Решение

  1. Инъекционная фабрика LoggedMessageS было бы хорошим решением, особенно если вы не хотите закрывать конструктор LoggedMessage против модификаций. В общем, хорошо отделить заботу о создании объекта от его использования.

  2. Простейшим решением было бы проверить конкретный тип вместо конкретного экземпляра:

    $ 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);
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]