Tanto quanto eu entendo, Factory
e as Proxy
classes são geradas em tempo real pelo carregador automático, se ainda não existirem var/generation
(veja: O que desencadeia a geração de uma fábrica no Magento 2 )
Mas por que recebo esse erro ao referenciar uma nova fábrica em um teste de unidade?
ReflectionException: A classe Magento \ Framework \ Api \ Search \ SearchCriteriaBuilderFactory não existe
[...] / vendor / magento / framework / TestFramework / Unit / Helper / ObjectManager.php: 161
use Magento\Framework\Api\Search\SearchCriteriaBuilderFactory;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
class SearchCriteriaTest extends \PHPUnit_Framework_TestCase
{
public function testFactoryGeneration()
{
$searchCriteriaBuilderFactory = (new ObjectManager($this))->getObject(SearchCriteriaBuilderFactory::class);
}
}
Estou usando o arquivo de inicialização dev/tests/unit/framework/bootstrap.php
.
Soluções alternativas que encontrei para gerar a classe:
usando o gerenciador de objetos real (Obrigado @DigitalPianism):
\Magento\Framework\App\Bootstrap::create(BP, $_SERVER)->getObjectManager()->create('\Magento\Framework\Api\Search\SearchCriteriaBuilderFactory')
executar
setup:di:compile
(dado que a fábrica é referenciada em um construtor)
Mas ainda espero encontrar uma solução limpa e com bom desempenho.
Além disso, não tenho certeza se está relacionado, mas create()
a fábrica gerada a partir do gerenciador de objetos de teste da unidade retorna null
, então eu ainda não tenho uma fábrica funcionando.
fonte
Magento\Framework\Api\Search\SearchCriteriaBuilder
?\Magento\Framework\App\Bootstrap::create(BP, $_SERVER)->getObjectManager()->create('\Magento\Framework\Api\Search\SearchCriteriaBuilderFactory');
?getObject
você ligargetBuilder
? Isso deve acontecer diretamente via,getObject
mas apenas para testar.Respostas:
A maneira mais fácil de lidar com isso é executar a compilação antes de executar os testes:
A outra maneira é definir explicitamente métodos para a simulação de fábrica, por exemplo. em vez de fazer isso:
Faça isso:
Em algum momento, tentei lidar com isso ligando
ObjectManager::getObject
antes de criar simulação, mas isso não parece uma solução limpa. Outra coisa é que não ajudou - ele criou um objeto, mas não salvou a classe em var / generation. Não mergulhei nisso mais.fonte
O problema se origina da biblioteca de simulação do PHPUnit, pois não pode carregar automaticamente a classe necessária.
Se você der uma olhada no repositório de desenvolvimento Magento, ele configura o Autoloader catcher, que gera uma classe quando solicitado. Se você criar um arquivo de inicialização semelhante no repositório do módulo, ele funcionará muito bem: https://github.com/magento/magento2/blob/develop/dev/tests/unit/framework/autoload.php
No entanto, aconselho o uso de uma abordagem diferente, utilizando um sistema de arquivos virtual, para que suas classes geradas materializadas não quebrem sua compilação se a assinatura da interface das classes geradas for alterada.
E então no seu arquivo de inicialização:
Eu estava usando uma abordagem semelhante ao criar um adaptador para o PHPSpec https://github.com/EcomDev/phpspec-magento-di-adapter/blob/master/src/Extension.php#L98
fonte
Além disso, você pode usar algo como isto
e someWhere no código apenas passa
fonte
$instanceName
e$factoryName
, caso tenha uma fábrica de interfaces que deva retornar modelos de dados.