Daher wird auf meinem gesamten System der folgende Code verwendet. Wir schreiben derzeit nachträglich Unit-Tests (besser spät als nie zuvor), aber ich sehe nicht ein, wie dies testbar wäre?
public function validate($value, Constraint $constraint)
{
$searchEntity = EmailAlertToSearchAdapter::adapt($value);
$queryBuilder = SearcherFactory::getSearchDirector($searchEntity->getKeywords());
$adapter = new SearchEntityToQueryAdapter($queryBuilder, $searchEntity);
$query = $adapter->setupBuilder()->build();
$totalCount = $this->advertType->count($query);
if ($totalCount >= self::MAXIMUM_MATCHING_ADS) {
$this->context->addViolation(
$constraint->message
);
}
}
Konzeptionell sollte dies auf jede Sprache anwendbar sein, aber ich benutze PHP. Der Code baut einfach ein ElasticSearch-Abfrageobjekt auf, das auf einem Search
Objekt basiert , das wiederum aus einem EmailAlert
Objekt aufgebaut ist. Dies Search
und EmailAlert
das sind nur POPOs.
Mein Problem ist, dass ich nicht sehe, wie ich das SearcherFactory
(das die statische Methode verwendet), noch das SearchEntityToQueryAdapter
, das die Ergebnisse von SearcherFactory::getSearchDirector
und die Search
Instanz benötigt, verspotten kann . Wie injiziere ich etwas, das aus Ergebnissen innerhalb einer Methode erstellt wird? Vielleicht gibt es ein Designmuster, das mir nicht bekannt ist?
Danke für jede Hilfe!
quelle
$this->context->addViolation
Aufrufs verwendet, innerhalb desif
.::
ist das für statische Methoden.::
ruft eine statische Methode für die Klasse auf.Antworten:
Es gibt einige Möglichkeiten, wie man
static
Methoden in PHP verspottet . Die beste Lösung, die ich verwendet habe, ist die AspectMock- Bibliothek, die über den Composer abgerufen werden kann (wie man statische Methoden verspottet, ist aus der Dokumentation ziemlich verständlich).Es handelt sich jedoch um eine kurzfristige Lösung für ein Problem, das auf eine andere Weise behoben werden sollte.
Wenn Sie den Layer, der für die Transformation von Abfragen zuständig ist, dennoch einem Komponententest unterziehen möchten, können Sie dies auf recht schnelle Weise tun.
Ich gehe jetzt davon aus, dass die
validate
Methode Teil einer Klasse ist. Die sehr schnelle Lösung, bei der Sie nicht alle statischen Aufrufe in Instanzaufrufe umwandeln müssen, besteht darin, Klassen zu erstellen, die als Proxys für Ihre statischen Methoden fungieren, und diese Proxys in Klassen einzufügen die zuvor die statischen Methoden verwendet.quelle
Zunächst würde ich vorschlagen, dies in separate Methoden aufzuteilen:
Dies versetzt Sie in eine Situation, in der Sie in Betracht ziehen können, diese beiden neuen Methoden öffentlich und Unit-Test
QueryTotal
undShowMessageWhenTotalExceedsMaximum
einzeln zu machen. Eine praktikable Option besteht darin, überhaupt keinen Unit-Test durchzuführenQueryTotal
, da Sie im Wesentlichen nur ElasticSearch testen würden. Das Schreiben eines Komponententests fürShowMessageWhenTotalExceedsMaximum
sollte einfach und viel sinnvoller sein, da dies Ihre Geschäftslogik tatsächlich testen würde.Wenn Sie "validieren" jedoch lieber direkt testen möchten, überlegen Sie, ob Sie die Abfragefunktion selbst als Parameter an "validieren" übergeben möchten (mit dem Standardwert "
$this->QueryTotal
). Auf diese Weise können Sie die Abfragefunktion ausspotten. Ich bin mir nicht sicher, ob ich die PHP-Syntax richtig verstanden habe. Falls dies nicht der Fall ist, lesen Sie dies bitte als "Pseudocode":quelle