Laravel在运行单元测试时保存到数据库

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Laravel在运行单元测试时保存到数据库相关的知识,希望对你有一定的参考价值。

我试图运行Laravel功能测试,使用Model Factory创建一些测试数据。

在其他测试中,在相同的目录和命名空间内,使用类似的“make”特征,数据库中不会保存任何条目。但是他们就是这个。

当使用app('env')时,它返回'testing',因此环境是正确的。

关于如何在不保存到mysql数据库的情况下运行这些测试的任何想法?

RoleTest

namespace Tests;

use TestsTraitsMakeRoleTrait;

class RoleTest extends BrowserKitTestCase
{
    use MakeRoleTrait;

    public function testGetChildren()
    {
        $childRoles = [];
        $baseRoles = [];

        for ($i = 0; $i < 4; $i++) {
            $parentId = null;

            if($i > 0){
                $parentId = $baseRoles[$i-1]->id;
            }

            $childRole = $this->makeRole();

            // Create base role
            $baseRoles[] =  $this->makeRole([
                'parent_id' => $parentId,
                'display_name' => $childRole->display_name,
                'site_id' => null
            ]);

            if($i < 3){
                $childRoles[] = $childRole;
            }
        }

        $children = $childRoles[0]->getChildren();

        $this->assertEquals($childRoles,$children);
    }
}

MakeRoleTrait

namespace TestsTraits;


use FakerFactory as Faker;
use AppModelsRole;
use AppRepositoriesRoleRepository;

trait MakeRoleTrait
{
    /**
     * Create fake instance of Role and save it in database
     *
     * @param array $roleFields
     * @return Role
     */
    public function makeRole($roleFields = [])
    {
        /** @var RoleRepository $roleRepo */
        $roleRepo = App::make(RoleRepository::class);
        $theme = $this->fakeRoleData($roleFields);
        return $roleRepo->skipPresenter()->create($theme);
    }

    /**
     * Get fake instance of Role
     *
     * @param array $roleFields
     * @return Role
     */
    public function fakeRole($roleFields = [])
    {
        return new Role($this->fakeRoleData($roleFields));
    }

    /**
     * Get fake data of Role
     *
     * @param array $roleFields
     * @return array
     */
    public function fakeRoleData($roleFields = [])
    {
        $role = factory(AppModelsRole::class,1)->make();
        $array = $role->first()->toArray();

        $array = array_merge(
            $array,
            $roleFields
        );

        return $array;
    }
}
答案

Laravel具有回滚对数据库所做的更改的特性。在5.6,它是the RefreshDatabase trait - 在一些早期版本it was DatabaseTransactions instead

应将这些特征添加到进行数据库更新/插入的所有测试中。

(为了更加方便(和安全),测试应该在单独的数据库连接上运行,也可以使用单独的数据库副本。)

以上是关于Laravel在运行单元测试时保存到数据库的主要内容,如果未能解决你的问题,请参考以下文章

Laravel - 输入未通过单元测试

PHP单元,使用单元测试测试laravel日志消息

使用单元测试时避免运行部分代码

使用 PHPUnit 对 Laravel 4 进行单元测试

如何使用内存数据库中的 sqlite 在 laravel 5.5 中运行单元测试

在 laravel 的测试套件中只运行一个单元测试