我已经创建了一个能够处理雄辩模型的程序包,并且已经为其创建了测试用例。
在某些时候,程序包应该为模型调用save()
或delete()
,这将尝试访问数据库。
第一次尝试I tried this approach和also this。关键是,在包的上下文中(甚至使用orchestra/testbench
),我需要配置数据库和迁移。由于该程序包本身没有任何模型(但是出于测试目的,我已经创建了 dummy模型),我认为这种方法可能会过大。无论如何,我仍然愿意在内存中设置一个准备好的sqlite db,我也尝试过但不能使其正常工作(它试图使用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进行测试。
最后但重要的注意事项::我不愿意测试模型本身,我愿意测试使用的代码(并因此取决于模型)。
答案 0 :(得分:2)
感谢Jonas Staudenmeir的评论:
与实际数据库的集成测试是测试代码的最彻底方法。 IMO,您至少应该对基本功能进行集成测试。 This is how我使用SQLite数据库进行程序包测试。
我可以配对并开始使用内存sqlite 方法。
Added Capsule test case setUp code按照this working project as example表示感谢(谢谢)
就我而言,我还需要安装sqlite驱动程序sudo apt-get install php7.2-sqlite
Tests now still run successfully,而该解决方案看起来更优雅,并且清理了功能替代解决方法,这些解决方法很容易在Eloquent Models的API升级时中断。这样还可以更轻松地访问测试包中与关系相关的功能。
答案 1 :(得分:1)
我认为您的第一个建议是实际数据库方法最好-使用软件包orchestra/testbench。
由于您的软件包中没有Eloquent模型,但是您的软件包会修改Eloquent模型,因此我认为您应该仅在测试文件夹中创建Eloquent模型以用于测试。
例如,将DummyContact
放入tests/Models/DummyContact.php
并将迁移文件放入tests/Database/Migration/DummyContactMigration.php
。
现在您要做的就是设置一个基本的TestCase.php
。
确保明确调用DummyContact
模型的迁移文件。
这里是一个示例:
<?php
namespace MyVendor\MyPackage\Tests;
use MyVendor\MyPackage\MyServiceProvider;
class TestCase extends \Orchestra\Testbench\TestCase
{
public function setUp(): void
{
parent::setUp();
$this->loadMigrationsFrom(__DIR__ . '/database/migrations');
$this->artisan('migrate', ['--database' => 'testbench'])->run();
}
/**
* add the package provider
*
* @param $app
* @return array
*/
protected function getPackageProviders($app)
{
return [MyServiceProvider::class];
}
/**
* Define environment setup.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
protected function getEnvironmentSetUp($app)
{
// Setup default database to use sqlite :memory:
$app['config']->set('database.default', 'testbench');
$app['config']->set('database.connections.testbench', [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
]);
}
}
您可能还想阅读本blog post