簡體   English   中英

Laravel 5.6對null成員函數beginTransaction()的單元測試調用

[英]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",

服務器上使用以下版本:

  • PHP 7.2
  • MongoDB 3.4
  • PHP MongoDB擴展1.4.2

我用供應商目錄中安裝的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM