J'ai donc le morceau de code suivant utilisé partout dans mon système. Nous écrivons actuellement des tests unitaires rétrospectivement (mieux vaut tard que jamais mon argument), mais je ne vois pas comment cela serait testable?
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
);
}
}
Conceptuellement, cela devrait être applicable à n'importe quel langage, mais j'utilise PHP. Le code construit simplement un objet de requête ElasticSearch, basé sur un Search
objet, qui à son tour est construit à partir d'un EmailAlert
objet. Ces Search
et EmailAlert
« s ne sont que POPO de.
Mon problème est que je ne vois pas comment je peux simuler le SearcherFactory
(qui utilise la méthode statique), ni le SearchEntityToQueryAdapter
, qui a besoin des résultats SearcherFactory::getSearchDirector
et de l' Search
instance. Comment injecter quelque chose qui se construit à partir des résultats dans une méthode? Peut-être y a-t-il un modèle de conception que je ne connais pas?
Merci pour toute aide!
la source
$this->context->addViolation
appel, à l'intérieur duif
.::
c'est pour les méthodes statiques.::
appelle une méthode statique sur la classe.Réponses:
Il y a quelques possibilités, comment se moquer des
static
méthodes en PHP, la meilleure solution que j'ai utilisée est la bibliothèque AspectMock , qui peut être extraite du composeur (comment se moquer des méthodes statiques est tout à fait compréhensible dans la documentation).Cependant, c'est un correctif de dernière minute pour un problème qui devrait être résolu d'une manière différente.
Si vous souhaitez toujours tester uniquement la couche responsable de la transformation des requêtes, il existe un moyen assez rapide de le faire.
Je suppose qu'en ce moment, la
validate
méthode fait partie d'une classe, la solution très rapide, qui ne vous oblige pas à transformer tous vos appels statiques en appel d'instance, consiste à créer des classes agissant en tant que proxy pour vos méthodes statiques et à injecter ces proxy dans des classes qui utilisait auparavant les méthodes statiques.la source
Tout d'abord, je suggère de diviser cela en plusieurs méthodes:
Cela vous laisse dans une situation où vous pouvez envisager de rendre ces deux nouvelles méthodes publiques et de test unitaire
QueryTotal
etShowMessageWhenTotalExceedsMaximum
individuellement. Une option viable ici est en fait de ne pas testerQueryTotal
du tout du tout, car vous ne testeriez essentiellement qu'ElasticSearch. La rédaction d'un test unitaireShowMessageWhenTotalExceedsMaximum
devrait être facile et beaucoup plus logique, car elle testerait en fait votre logique métier.Si, cependant, vous préférez tester "valider" directement, envisagez de passer la fonction de requête elle-même comme paramètre dans "valider" (avec une valeur par défaut de
$this->QueryTotal
), cela vous permettra de simuler la fonction de requête. Je ne sais pas si j'ai bien compris la syntaxe PHP, donc dans le cas contraire, veuillez lire ceci comme "Pseudo code":la source