php - 是否可以在 PHP 中模拟 PECL 扩展?

标签 php unit-testing phpunit mockery

我正在开发 datastax cassandra extension 的包装器.

扩展的简单用法如下所示,它尝试连接到 127.0.0.1:9042 上的 Cassandra 服务器:

$connection = \Cassandra::cluster()->build()->connect(); // instance of \Cassandra\DefaultSession

显然它会出错,因为没有可用的正在运行的服务器。

我试图一步一步模拟所有这些调用,但它不起作用。 对于mockery/mockery包,主要问题是:

  • \Cassandra\Cassandra\Cluster\Builder\Cassandra\DefaultSession 均定义为最终类
  • 所有类均已预加载,因此代理和部分模拟不起作用
  • 我不想在我的机器上运行 cassandra 服务器,因为它无法处理如此繁重的服务器,而且我想为我正在开发的包设置一个 CI

知道如何处理这种情况吗?

最佳答案

您可以采取一些措施来避免在测试中模拟整个宇宙。

在这种特定情况下,创建 CassandraSessionFactory 已经足以让您更轻松地注入(inject)/模拟事物。

不过,我建议将存储库职责隔离到一个接口(interface)中,并进行特定于 Cassandra 的实现。

例如,假设您有一个 Person 集合/表。并且您希望您的程序能够获取它们。然后,您可以使用 fetchBySomething(): Person 方法创建一个 PersonRepository 接口(interface)。稍后您将能够创建一个名为 CassandraPersonRepository 的具体实现,它使用正确的扩展来实现此功能。

通过上面的内容,您可以通过仅模拟其接口(interface)来单元测试需要 PersonRepository 的所有内容。并仅对 CassandraPersonRepository 连接进行合约测试

查看这篇文章:https://thephp.website/en/issue/clean-tests-with-php-and-phpunit/ 有两个部分对您的情况有所帮助:“测试不应有 I/O 操作”和“始终注入(inject)依赖项”。它们展示了实现我刚才提到的目标的快速方法。

额外提示:使用 Prophecy 而不是 phpunit 的 Mock。更容易,甚至更快。

我希望这个答案有用:)

干杯!

关于php - 是否可以在 PHP 中模拟 PECL 扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59777629/

相关文章:

javascript - 持久性刷新倒计时

php - SQL 编码问题 (Â)

php - 如何使用 PHPUnit 对异常进行单元测试?

laravel - 在所有其他单元测试之前在 Laravel 中运行特定的单元测试 (phpunit)

laravel - 创建 Cashier 订阅以进行测试

php - 特定表的 JOIN 查询

php - CodeIgniter:在一个循环中显示两个表中的数据

visual-studio - 在 F# Interactive 上运行 F# 测试

java - Maven:如何设置 Maven 以分别运行单元测试和集成测试

javascript - 在 sinon 中 stub 依赖函数