如何测试处理Eloquent模型的Laravel包?

问题描述 投票:3回答:1

我已经创建了一个操作雄辩模型的包,我已经为它创建了测试用例。

该软件包应该在某些时候为模型调用save()delete(),它会尝试访问数据库。

Actual Database approach

作为第一次尝试I tried this approachalso this。关键是在包的上下文中(甚至使用orchestra/testbench)我需要配置数据库和迁移。由于软件包本身没有任何模型(但我为测试目的创建了一个虚拟模型),我认为这种方法可能过度。在任何情况下,我仍然接受在内存中设置一个准备好的sqlite数据库,我也试过但无法使它工作(它试图使用forge连接而不是sqlite,我无法让它访问另一个连接。我可能提供我为此所做的事情的详细信息。

Mocking approach

另一种可能的尝试(根据我对此的有限理解)是部分模拟模型。但是在我嘲笑之后,它不知道如何处理其他调用,例如fill(),我愿意为此采取常见行为,但是我收到了一个未找到异常的方法。

Method override approach

鉴于这两种可能的尝试都很糟糕,我违反了第三种可能对我有用的方法,但老实说我不确定这是不是可行的方法。

为了避免在调用save()delete()方法时由于缺少数据库而导致测试失败,我覆盖了它们(full source code here):

class DummyContact extends Model
{
    // ...

    public function save(array $options = [])
    {
        $this->exists = true;
        $this->wasRecentlyCreated = true;
    }

    public function delete()
    {
        $this->exists = false;
        $this->wasRecentlyCreated = false;
    }
}

这样,我就可以测试以下代码(full source here):

public function unifyOnBase()
{
    $mergeModel = $this->merge();

    $this->modelA->fill($mergeModel->toArray());
    $this->modelA->save();
    $this->modelB->delete();

    return $this->modelA;
}

所以我的问题是,这种方法是否可以接受? (我认为这是公平的,我没有看到特别的陷阱,但我怀疑存在更优雅的方法)。如果有建议的方法,如模拟或使用实际的数据库来运行测试,我想知道what adaptations should I do to my testing codebase采取它们。

最后但重要的注意事项:我不愿意自己测试模型,我愿意测试我使用的代码(因此取决于模型)。

php laravel unit-testing eloquent mocking
1个回答
2
投票

感谢Jonas Staudenmeir的评论:

与实际数据库的集成测试是测试代码的最彻底的方法。 IMO,你至少应该对基本功能进行集成测试。 This is how我使用SQLite数据库来测试我的包。

我可以配对并开始使用内存中的sqlite方法。

  1. Removed override functions
  2. Added Capsule test case setUp code按照this working project as example(谢谢你)
  3. 在我的情况下,我还需要安装sqlite驱动程序sudo apt-get install php7.2-sqlite

Tests now still run successfully,虽然解决方案看起来更优雅,并清理功能覆盖变通方法,这很容易破坏Eloquent模型的API升级。这还可以更轻松地访问包的测试关系相关功能。

Test pass

© www.soinside.com 2019 - 2024. All rights reserved.