ala*_*iva 5 php unit-testing mocking laravel eloquent
我创建了一个操作 eloquent 模型的包,并为它创建了测试用例。
该包应该调用save()或delete()模型,在某些时候会尝试访问数据库。
作为第一次尝试,我尝试了这种方法以及这种. 关键是在包的上下文中(甚至使用orchestra/testbench),我需要配置数据库和迁移。由于包本身没有任何模型(但我为测试目的创建了一个虚拟模型)我认为这种方法可能有点矫枉过正。无论如何,我仍然接受在内存中设置一个准备好的sqlite db,我也尝试过但无法使其工作(它试图使用forge连接sqlite,但我无法使其访问另一个连接。我可以提供详细信息关于我为它所做的)。
另一种可能的尝试(根据我对此的有限理解)是部分模拟模型。但是在我嘲笑它之后,它不知道如何处理其他调用,例如fill()我愿意的常见行为,但是我收到了一个方法未找到异常。
鉴于这两种可能的尝试都失败了,我默认采用对我有用的第三种可能的方法,但老实说,我不确定这是否是解决方法。
为了避免在调用save()或delete()方法时由于缺少数据库而导致测试失败,我覆盖了它们(完整源代码在这里):
class DummyContact extends Model
{
    // ...
    public function save(array $options = [])
    {
        $this->exists = true;
        $this->wasRecentlyCreated = true;
    }
    public function delete()
    {
        $this->exists = false;
        $this->wasRecentlyCreated = false;
    }
}
public function unifyOnBase()
{
    $mergeModel = $this->merge();
    $this->modelA->fill($mergeModel->toArray());
    $this->modelA->save();
    $this->modelB->delete();
    return $this->modelA;
}
所以我的问题是,这种方法可以接受吗?(我认为这是公平的,我没有看到特殊的陷阱,但我怀疑存在更优雅的方法)。如果有建议的方法,比如 Mocking 或使用实际的 DB 来运行测试,我想知道我应该对我的测试代码库进行哪些调整以进行测试。
最后但重要的说明:我不愿意测试模型本身,我愿意测试我使用的代码(因此取决于模型)。
感谢 Jonas Staudenmeir 的评论:
与实际数据库的集成测试是测试代码的最彻底的方法。IMO,您至少应该对基本功能进行集成测试。这就是我如何使用 SQLite 数据库来测试我的包。
我可以配对并开始使用内存中的 sqlite方法。
按照此工作项目添加了 Capsule 测试用例设置代码作为示例(谢谢)
就我而言,我还需要安装 sqlite 驱动程序sudo apt-get install php7.2-sqlite
现在测试仍然可以成功运行,而解决方案看起来更优雅,并清理了函数覆盖变通办法,这些变通办法很容易在 Eloquent 模型的 API 升级时被破坏。这还可以更轻松地访问测试包的依赖于关系的功能。
| 归档时间: | 
 | 
| 查看次数: | 952 次 | 
| 最近记录: |