Portanto, tenho o seguinte trecho de código em uso em todo o meu sistema. No momento, estamos escrevendo testes de unidade retrospectivamente (antes tarde do que nunca foi o meu argumento), mas não vejo como isso seria testável?
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
);
}
}
Conceitualmente, isso deve ser aplicável a qualquer idioma, mas estou usando PHP. O código simplesmente cria um objeto de consulta ElasticSearch, com base em um Search
objeto, que por sua vez é criado a partir de um EmailAlert
objeto. Estes Search
e EmailAlert
são apenas POPO.
Meu problema é que não vejo como zombar do SearcherFactory
(que usa o método estático), nem do SearchEntityToQueryAdapter
, que precisa dos resultados SearcherFactory::getSearchDirector
e da Search
instância. Como injeto algo que é construído a partir de resultados em um método? Talvez haja algum padrão de design que eu não conheça?
Obrigado por qualquer ajuda!
fonte
$this->context->addViolation
chamada, dentro daif
.::
é para métodos estáticos.::
chama um método estático na classe.Respostas:
Existem algumas possibilidades, como zombar de
static
métodos em PHP, a melhor solução que usei é a biblioteca AspectMock , que pode ser acessada pelo compositor (como zombar de métodos estáticos é bastante compreensível na documentação).No entanto, é uma correção de última hora para um problema que deve ser corrigido de uma maneira diferente.
Se você ainda deseja testar a camada responsável pela transformação de consultas, há uma maneira bem rápida de fazer isso.
Estou assumindo que agora o
validate
método faz parte de alguma classe, a correção muito rápida, que não exige que você transforme todas as chamadas estáticas em chamadas de instância, é criar classes agindo como proxies para seus métodos estáticos e injetar esses proxies em classes que usava anteriormente os métodos estáticos.fonte
Primeiro, sugiro dividir isso em métodos separados:
Isso deixa você em uma situação em que você pode considerar tornar esses dois novos métodos públicos e teste de unidade
QueryTotal
eShowMessageWhenTotalExceedsMaximum
individualmente. Uma opção viável aqui é, na verdade, não fazer teste de unidadeQueryTotal
, pois você basicamente testaria apenas o ElasticSearch. Escrever um teste de unidadeShowMessageWhenTotalExceedsMaximum
deve ser fácil e faz muito mais sentido, pois na verdade testaria sua lógica de negócios.Se, no entanto, você preferir testar "validar" diretamente, considere passar a função de consulta em si como um parâmetro para "validate" (com um valor padrão de
$this->QueryTotal
), isso permitirá que você zombe da função de consulta. Não tenho certeza se obtive a sintaxe do PHP correta. Caso contrário, leia isto como "Pseudo código":fonte