2016-09-10 1 views
1
etwas instanziiert

Sagen wir, ich diese Klasse haben, dass ich spec-ing (in Anlehnung an BDD-Ansatz)Spec-ing eine Klasse, die

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); 
    } 
} 

und LoggedMessage ist wie folgt definiert

class LoggedMessage 
{ 
    private $date; 

    private $message; 

    public function __construct(Message $message) 
    { 
     $this->date = new \DateTime(); 
     $this->message = $message; 
    } 
} 

Manchmal meine Spezifikationsbeispiel schlägt aufgrund der Diskrepanz von Message Datum instanziiert in der Spezifikation und der in der Logger Klasse.

class LoggerSpec 
{ 
    public function it_logs_a_message(Message $message, EntityManager $em) 
    { 
     $log = new LoggedMessage($message); 
     $em->persist($log)->shouldBeCalled(1); 

     $this->logMessageAsRead($message); 
    } 
} 

Frage Nummer eins: Muss ich einen Geruch in meinem Code haben, so muss ich einen Mitarbeiter schaffen (dh .: eine Fabrik) und injizieren sie in Logger, um einen neuen LoggedMessage zu schaffen?

Frage Nummer zwei: Wenn es nicht notwendig ist, einen neuen Mitarbeiter zu injizieren, wie kann ich sicher sein, dass meine Spezifikation jedes Mal funktioniert und aufgrund zufälliger Datumdiskrepanz nicht zufällig ausfällt?

Antwort

0
  1. Ein injiziert Fabrik LoggedMessage s wäre eine gute Lösung sein, vor allem wenn Sie wollen den Konstruktor von LoggedMessage gegen Änderungen nicht schließen. Im Allgemeinen ist es gut, das Anliegen, ein Objekt zu erstellen, von der Verwendung zu trennen.

  2. wäre die einfachste Lösung für einen bestimmten Typ anstelle eines konkreten Fall zu prüfen sein:

    Ausführungs $> anhalten (Argument :: type (LoggedMessage :: Klasse)) -> shouldBeCalled (1);

Wenn Sie Ihre Erwartung wollen genauer sein, können Sie Argument::which oder Argument::that verwenden:

$em->persist(Argument::which('getMessage', $message))->shouldBeCalled(1); 
$em->persist(Argument::that(function($arg) { 
    return $arg->getDate() instanceof \DateTime; 
}))->shouldBeCalled(1); 
+0

Dank für Ihre Antwort danken. Alle deine Überlegungen sind die gleichen wie meine, also denke ich, dass eine Fabrik der einzige Weg ist, dies zu tun. Der zweite Punkt ist jedoch nicht gut: Für dieses Beispiel ist es zu wenig tighter (phpspec Beispiel ist klar) – DonCallisto

Verwandte Themen