我已经创建了一个操作雄辩模型的包,我已经为它创建了测试用例。
该软件包应该在某些时候为模型调用save()
或delete()
,它会尝试访问数据库。
作为第一次尝试I tried this approach和also this。关键是在包的上下文中(甚至使用orchestra/testbench
)我需要配置数据库和迁移。由于软件包本身没有任何模型(但我为测试目的创建了一个虚拟模型),我认为这种方法可能过度。在任何情况下,我仍然接受在内存中设置一个准备好的sqlite数据库,我也试过但无法使它工作(它试图使用forge
连接而不是sqlite
,我无法让它访问另一个连接。我可能提供我为此所做的事情的详细信息。
另一种可能的尝试(根据我对此的有限理解)是部分模拟模型。但是在我嘲笑之后,它不知道如何处理其他调用,例如fill()
,我愿意为此采取常见行为,但是我收到了一个未找到异常的方法。
鉴于这两种可能的尝试都很糟糕,我违反了第三种可能对我有用的方法,但老实说我不确定这是不是可行的方法。
为了避免在调用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采取它们。
最后但重要的注意事项:我不愿意自己测试模型,我愿意测试我使用的代码(因此取决于模型)。
感谢Jonas Staudenmeir的评论:
与实际数据库的集成测试是测试代码的最彻底的方法。 IMO,你至少应该对基本功能进行集成测试。 This is how我使用SQLite数据库来测试我的包。
我可以配对并开始使用内存中的sqlite方法。
sudo apt-get install php7.2-sqlite
Tests now still run successfully,虽然解决方案看起来更优雅,并清理功能覆盖变通方法,这很容易破坏Eloquent模型的API升级。这还可以更轻松地访问包的测试关系相关功能。