Así que tengo el siguiente código en uso en todo mi sistema. Actualmente estamos escribiendo pruebas unitarias retrospectivamente (mejor tarde que nunca fue mi argumento), pero no veo cómo esto sería comprobable.
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
);
}
}
Conceptualmente, esto debería ser aplicable a cualquier lenguaje, pero estoy usando PHP. El código simplemente crea un objeto de consulta ElasticSearch, basado en un Search
objeto, que a su vez está construido a partir de un EmailAlert
objeto. Estos Search
y EmailAlert
's son solo POPO's.
Mi problema es que no veo cómo puedo burlarme del SearcherFactory
(que usa el método estático), ni del SearchEntityToQueryAdapter
, que necesita los resultados SearcherFactory::getSearchDirector
y la Search
instancia. ¿Cómo se inyecta algo que se genera a partir de resultados dentro de un método? ¿Tal vez hay algún patrón de diseño que no conozco?
¡Gracias por cualquier ayuda!
fuente
$this->context->addViolation
llamada, dentro delif
.::
es para métodos estáticos.::
llama a un método estático en la clase.Respuestas:
Hay algunas posibilidades, cómo burlarse de los
static
métodos en PHP, la mejor solución que he usado es la biblioteca AspectMock , que se puede extraer a través del compositor (cómo burlarse de los métodos estáticos es bastante comprensible de la documentación).Sin embargo, es una solución de último minuto para un problema que debería solucionarse de una manera diferente.
Si aún desea probar la capa responsable de la transformación de las consultas, hay una forma bastante rápida de hacerlo.
Supongo que en este momento el
validate
método es parte de alguna clase, la solución muy rápida, que no requiere que transforme todas sus llamadas estáticas a llamada de instancia, es construir clases que actúen como proxies para sus métodos estáticos e inyectar estos proxies en clases que anteriormente usaba los métodos estáticos.fuente
Primero, sugeriría dividir esto en métodos separados:
Esto lo deja en una situación en la que puede considerar hacer públicos esos dos nuevos métodos y realizar pruebas unitarias
QueryTotal
eShowMessageWhenTotalExceedsMaximum
individuales. Una opción viable aquí es en realidad no hacer una prueba unitariaQueryTotal
, ya que esencialmente probaría solo ElasticSearch. Escribir una prueba unitariaShowMessageWhenTotalExceedsMaximum
debería ser fácil y tiene mucho más sentido, ya que en realidad pondría a prueba la lógica de su negocio.Sin embargo, si prefiere probar "validar" directamente, considere pasar la función de consulta como un parámetro a "validar" (con un valor predeterminado de
$this->QueryTotal
), esto le permitirá simular la función de consulta. No estoy seguro de tener la sintaxis PHP correcta, por lo que en caso de que no lo haya hecho, léalo como "Pseudocódigo":fuente