许多现代数据库应用程序都使用Doctrine ORM项目。
将数据库与服务一起使用是一种很好的做法。 服务需要进行测试。
要测试服务,可以连接测试数据库,也可以锁定实体管理器和存储库。 使用第一个选项,一切都是清楚的,但是部署数据库来测试服务并非总是有意义。 我们将讨论这个。
例如,采取以下服务:
src /服务/用户/ UserService.php 我们需要测试其唯一的create()
方法。
选择以下情况:
- 无需引荐来源即可成功创建用户
- 使用引荐来源网址成功创建用户
- 错误“已登录”
- 错误“找不到引荐来源网址”
为了测试服务,我们需要一个实现Doctrine\ORM\EntityManagerInterface
接口的对象
选项1.我们使用真实的数据库
我们将为测试编写一个基类,稍后我们将继承该基类。
现在,测试可以设置环境变量了。 将它们添加到php
部分的phpunit.xml
文件中。 我将使用sqlite db
phpunit.xml <?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.1/phpunit.xsd" bootstrap="vendor/autoload.php" executionOrder="depends,defects" forceCoversAnnotation="true" beStrictAboutCoversAnnotation="true" beStrictAboutOutputDuringTests="true" beStrictAboutTodoAnnotatedTests="true" verbose="true" colors="true"> <php> <env name="DB_DRIVER" value="pdo_sqlite" /> <env name="DB_PATH" value="var/db-test.sqlite" /> <env name="DB_USER" value="" /> <env name="DB_PASSWORD" value="" /> <env name="DB_NAME" value="" /> </php> <testsuites> <testsuite name="default"> <directory>tests/Unit</directory> </testsuite> </testsuites> <filter> <whitelist processUncoveredFilesFromWhitelist="true"> <directory suffix=".php">src</directory> </whitelist> </filter> </phpunit>
现在我们将编写一个服务测试
测试/单位/服务/ UserServiceTest.php 确保我们的服务正常运行
./vendor/bin/phpunit
选项2.使用MockBuilder
每次都很难建立数据库。 尤其是phpunit使我们有机会使用mockBuilder即时收集moki。 可以在Symfony文档中找到一个示例。
该选项正在工作,但是存在问题。 您需要清楚地知道代码以什么顺序访问EntityManager方法。
例如,如果开发人员将检查替换为引荐来源网址,然后将检查替换为繁忙登录,则测试将失败。 但是应用程序不是。
我提出了智能调用EntityManager的选项,该选项将其所有数据存储在内存中,并且不使用真实的数据库。
选项3.我们使用MockBuilder将数据存储在内存中。
为了提高灵活性,我们将添加一个环境变量,以便您可以使用真实的数据库。 让我们在phpunit.xml
越冬
phpunit.xml更改 <?xml version="1.0" encoding="UTF-8"?> <php> <env name="EMULATE_BD" value="1" /> </php>
现在修改基类
现在,我们可以再次运行测试,并确保我们的服务无需连接数据库即可正常工作。
./vendor/bin/phpunit
Github上可用的源代码