以下是扩展BaseEntityManager的代码的一部分:
namespace Vop\PolicyBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Persistence\ObjectRepository;
use Sonata\CoreBundle\Model\BaseEntityManager;
class AdditionalInsuredTypeManager extends BaseEntityManager
{
/**
* @param int $productId
*
* @return ArrayCollection
*/
public function getProductInsuredTypes($productId = null)
{
$repository = $this->getRepository();
$allActiveTypes = $repository->findAllActive();
// other code
}
/**
* @return AdditionalInsuredTypeRepository|ObjectRepository
*/
protected function getRepository()
{
return parent::getRepository();
}
}
在这里,我正在尝试编写单元测试:
public function testGetProductInsuredTypes()
{
$managerRegistry = $this->getMockBuilder(\Doctrine\Common\Persistence\ManagerRegistry::class)
->getMock();
$additionalInsuredTypeManager = new AdditionalInsuredTypeManager(
AdditionalInsuredTypeManager::class,
$managerRegistry
);
$additionalInsuredTypeManager->getProductInsuredTypes(null);
}
有什么问题:
无法找到类Vop \ PolicyBundle \ Entity \ AdditionalInsuredTypeManager的映射信息。请检查' auto_mapping'选项(http://symfony.com/doc/current/reference/configuration/doctrine.html#configuration-overview)或将捆绑包添加到'映射'学说配置中的部分。 /home/darius/PhpstormProjects/vop/vendor/sonata-project/core-bundle/Model/BaseManager.php:54 /home/darius/PhpstormProjects/vop/vendor/sonata-project/core-bundle/Model/BaseManager.php:153 /home/darius/PhpstormProjects/vop/src/Vop/PolicyBundle/Entity/AdditionalInsuredTypeManager.php:46 /home/darius/PhpstormProjects/vop/src/Vop/PolicyBundle/Entity/AdditionalInsuredTypeManager.php:21 /home/darius/PhpstormProjects/vop/src/Vop/PolicyBundle/Tests/Unit/Entity/AdditionalInsuredTypeManagerTest.php:22
我不知道如何修复此错误,但这实际上需要对扩展我认为的BaseEntityManager做一些事情。
我看到错误是由这一行引起的:
$repository = $this->getRepository();
我甚至无法从构造函数中注入存储库,因为父构造函数没有这样的参数。
关于测试的信息非常少:
https://sonata-project.org/bundles/core/master/doc/reference/testing.html
答案 0 :(得分:0)
我不能告诉你测试你的存储库是否有用,除了你很可能不会扩展doctrine的实体经理之外,我也不能指出你的错误。如果有任何东西使用自定义EntityRepository或编写一个注入EntityManager的服务(或更好的EntityRegistry):
class MyEntityManager
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function getProductInsuredTypes($productId = null)
{
$repository = $this->entityManager->getRepository(Product::class);
$allActiveTypes = $repository->findAllActive();
// other code
}
}
我能给你的是解释我如何处理测试存储库:
我认为单元测试,尤其是模拟测试,看起来有点浪费。它们只会将您绑定到当前的实现,并且由于任何相关性被嘲笑,您很可能不会测试任何行为。
可能有用的是进行功能测试,其中提供真实的数据库连接,然后对存储库执行查询以查看它是否确实返回了预期的结果。我通常这样做是为了更复杂的查询或使用高级教义功能,如使用自定义ResultsetMap的本机查询。在这种情况下,您不会模拟EntityManager,而是使用Doctrine的TestHelper来创建内存中的sqlite数据库。这看起来像这样:
protected $entityManager;
protected function setUp()
{
parent::setUp();
$config = DoctrineTestHelper::createTestConfiguration();
$config->setNamingStrategy(new UnderscoreNamingStrategy());
$config->setRepositoryFactory(new RepositoryFactory());
$this->entityManager = DoctrineTestHelper::createTestEntityManager($config);
}
缺点是,您将手动注册自定义类型和侦听器,这意味着行为可能与您的生产配置不同。此外,您仍然需要设置架构并为测试提供夹具。您也很可能不会在生产中使用SQLite,因此这是另一个偏差。好处是您不必在运行之间处理清理数据库,并且可以轻松地并行运行测试,而且通常比设置完整的测试数据库更快更容易。
最终选项与前一个选项有些接近。您可以拥有一个测试数据库,您可以在参数,环境变量或config_test.yml
中定义,然后可以引导内核并从DI容器中获取实体管理器。 Symfony的WebTestCase可以作为这种方法的参考。
缺点是,您必须启动内核并确保具有用于开发,生产和测试的单独数据库设置,以确保您的测试数据不会弄乱任何内容。您还必须设置您的架构和灯具,此外,您可以轻松地遇到测试未被隔离并开始变得棘手的问题,例如:以不同顺序运行或仅运行部分测试套件时。显然,由于这是通过引导应用程序进行的完全集成测试,因此与单元测试或较小功能测试相比,性能足迹明显更高,而应用程序缓存可能会给您带来额外的麻烦。
根据经验:
TL;博士