As far as I understand, Factory
and Proxy
classes are generated on the fly by the autoloader if they do not exist yet in var/generation
(see: What Triggers the Generation of a Factory in Magento 2)
But why do I get this error when referencing a new factory in a unit test?
ReflectionException: Class
Magento\Framework\Api\Search\SearchCriteriaBuilderFactory does not
exist[…]/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);
}
}
I am using the bootstrap file dev/tests/unit/framework/bootstrap.php
.
Workarounds I found to generate the class:
-
using the real object manager (Thanks @DigitalPianism):
\Magento\Framework\App\Bootstrap::create(BP, $_SERVER)->getObjectManager()->create('\Magento\Framework\Api\Search\SearchCrite‌​riaBuilderFactory')
-
run
setup:di:compile
(given the factory is referenced in a constructor)
But I still hope to find a clean and performant solution.
Also, not sure if related, but create()
of the generated factory from the unit test object manager returns null
, so I don't even have a working factory yet.
Best Answer
The easiest way to deal with that is to run compilation before running tests:
The other way is to explicitly define methods for the factory mock eg. instead of doing this:
Do this:
At some point, I tried to deal with that by calling
ObjectManager::getObject
before creating mock, but this doesn't look as a clean solution. Another thing is that it didn't help - it created an object, but did not save class in var/generation. I haven't dig into this more.