![](/img/trans.png)
[英]Laravel 5 Unit Test - Call to a member function connection() on null
[英]Laravel 5.6 Unit Test Call to a member function beginTransaction() on null
我有一個運行版本5.6的Laravel項目。 連接的數據庫是mongodb,帶有jenssegers / mongodb軟件包。
我編寫了一個單元測試來測試與用戶相關的功能。
該測試在已配置的測試mongodb數據庫中創建新用戶。 我想在每次測試運行后刷新數據庫,所以我使用RefreshDatabase
Trait。
使用RefreshDatabase
Trait時,運行測試時出現以下錯誤:
有1個錯誤:
1)Tests \\ Unit \\ UserTest :: it_gets_top_user錯誤:在null上調用成員函數beginTransaction()
當不使用Trait時,測試將在數據庫中創建所有必要的內容並執行斷言而不會出錯。
測試如下所示:
/** @test */
public function it_gets_top_user()
{
factory(\App\Users\User::class, 5)->create();
$userOne = factory(\App\Users\User::class)->create([
'growth' => 10
]);
$topUser = Users::getTopUser();
$collection = new Collection();
$collection->push($userOne);
$this->assertEquals($collection, $topUser);
}
我在composer.json中使用以下版本:
"laravel/framework": "5.6.*",
"jenssegers/mongodb": "3.4.*",
"phpunit/phpunit": "~7.0",
服務器上使用以下版本:
我用供應商目錄中安裝的phpunit調用測試:
vendor/phpunit/phpunit/phpunit
問題似乎是RefreshDatabase
Trait對於MongoDB環境根本不起作用。
我通過在Laravel項目的testing/
目錄中創建自己的RefreshDatabase
Trait解決了上述問題。
該特質看起來像這樣:
<?php
namespace Tests;
trait RefreshDatabase
{
/**
* Define hooks to migrate the database before and after each test.
*
* @return void
*/
public function refreshDatabase()
{
$this->dropAllCollections();
}
/**
* Drop all collections of the testing database.
*
* @return void
*/
public function dropAllCollections()
{
$database = $this->app->make('db');
$this->beforeApplicationDestroyed(function () use ($database) {
// list all collections here
$database->dropCollection('users');
});
}
}
為了啟用此特性,我重寫了TestCase
類中的setUpTraits
函數。 現在看起來像這樣:
/**
* Boot the testing helper traits.
*
* @return array
*/
protected function setUpTraits()
{
$uses = array_flip(class_uses_recursive(static::class));
if (isset($uses[\Tests\RefreshDatabase::class])) {
$this->refreshDatabase();
}
if (isset($uses[DatabaseMigrations::class])) {
$this->runDatabaseMigrations();
}
if (isset($uses[DatabaseTransactions::class])) {
$this->beginDatabaseTransaction();
}
if (isset($uses[WithoutMiddleware::class])) {
$this->disableMiddlewareForAllTests();
}
if (isset($uses[WithoutEvents::class])) {
$this->disableEventsForAllTests();
}
if (isset($uses[WithFaker::class])) {
$this->setUpFaker();
}
return $uses;
}
最后,在所有測試類中,我可以像這樣使用新創建的Trait:
<?php
namespace Tests\Unit;
use Illuminate\Database\Eloquent\Collection;
use Tests\RefreshDatabase;
use Tests\TestCase;
class UserTest extends TestCase
{
use RefreshDatabase;
// tests happen here
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.