是否可以在 PHP 中模拟 PECL 扩展?
Is it possible to mock a PECL extension in PHP?
我正在为 datastax cassandra extension 开发包装器。
扩展的简单用法如下所示,它尝试连接到 127.0.0.1:9042
上的 Cassandra 服务器:
$connection = \Cassandra::cluster()->build()->connect(); // instance of \Cassandra\DefaultSession
显然它会出错,因为没有 运行ning 服务器可用。
我试着一步一步地模拟所有这些调用,但它不起作用。
使用包 mockery/mockery
的主要问题是:
\Cassandra
、\Cassandra\Cluster\Builder
和 \Cassandra\DefaultSession
都定义为最终 类
- 所有 类 都已预加载,因此代理和部分模拟不起作用
- 我不想在我的机器上 运行 一个 cassandra 服务器,因为它无法处理这么重的服务器,而且我想为我正在开发的包设置一个 CI
知道如何处理这种情况吗?
您应该围绕 cassandra 开发适配器 API,然后在测试中模拟/替换它。
您可以采取一些措施来避免在测试中模拟整个宇宙。
在这种特定情况下,创建 CassandraSessionFactory
可能已经足以让您更轻松地 inject/mock 事情。
不过,我建议将存储库职责分离到一个接口中,并进行特定于 Cassandra 的实现。
例如,假设您有 Person
collection/table。并且您希望您的程序能够获取它们。然后,您将使用 fetchBySomething(): Person
方法创建一个 PersonRepository
接口。稍后您将能够创建一个名为 CassandraPersonRepository
的具体实现,它使用适当的扩展来实现它。
有了上面的这个,你可以 单元测试 所有需要 PersonRepository
的东西,只需要模拟它的接口。并仅针对 CassandraPersonRepository
连接进行 合同测试 。
检查此 post:https://thephp.website/en/issue/clean-tests-with-php-and-phpunit/
有两个部分对您的案例有帮助:"Tests should have no I/O operations" 和 "Always inject dependencies"。他们展示了实现我刚才提到的目标的快速方法。
额外提示:使用 Prophecy 而不是 phpunit 的 Mock。更容易,甚至更快。
我希望这个回答有用:)
干杯!
我正在为 datastax cassandra extension 开发包装器。
扩展的简单用法如下所示,它尝试连接到 127.0.0.1:9042
上的 Cassandra 服务器:
$connection = \Cassandra::cluster()->build()->connect(); // instance of \Cassandra\DefaultSession
显然它会出错,因为没有 运行ning 服务器可用。
我试着一步一步地模拟所有这些调用,但它不起作用。
使用包 mockery/mockery
的主要问题是:
\Cassandra
、\Cassandra\Cluster\Builder
和\Cassandra\DefaultSession
都定义为最终 类- 所有 类 都已预加载,因此代理和部分模拟不起作用
- 我不想在我的机器上 运行 一个 cassandra 服务器,因为它无法处理这么重的服务器,而且我想为我正在开发的包设置一个 CI
知道如何处理这种情况吗?
您应该围绕 cassandra 开发适配器 API,然后在测试中模拟/替换它。
您可以采取一些措施来避免在测试中模拟整个宇宙。
在这种特定情况下,创建 CassandraSessionFactory
可能已经足以让您更轻松地 inject/mock 事情。
不过,我建议将存储库职责分离到一个接口中,并进行特定于 Cassandra 的实现。
例如,假设您有 Person
collection/table。并且您希望您的程序能够获取它们。然后,您将使用 fetchBySomething(): Person
方法创建一个 PersonRepository
接口。稍后您将能够创建一个名为 CassandraPersonRepository
的具体实现,它使用适当的扩展来实现它。
有了上面的这个,你可以 单元测试 所有需要 PersonRepository
的东西,只需要模拟它的接口。并仅针对 CassandraPersonRepository
连接进行 合同测试 。
检查此 post:https://thephp.website/en/issue/clean-tests-with-php-and-phpunit/ 有两个部分对您的案例有帮助:"Tests should have no I/O operations" 和 "Always inject dependencies"。他们展示了实现我刚才提到的目标的快速方法。
额外提示:使用 Prophecy 而不是 phpunit 的 Mock。更容易,甚至更快。
我希望这个回答有用:)
干杯!