Laravel Laravel
  • 前言

    • 发行说明
    • 升级向导
    • 贡献导引
    • API 文档
  • 入门指南

    • 安装
    • 配置
    • 文件夹结构
    • Homestead
    • Valet
    • 部署
  • 架构思想

    • 请求生命周期
    • 服务容器
    • 服务提供者
    • Facades:门面
    • Contracts:契约
  • 基础功能

    • 路由
    • 中间件
    • CSRF 保护
    • 控制器
    • 请求
    • 响应
    • 视图
    • URL 生成
    • Session
    • 表单验证
    • 错误处理
    • 日志
  • 前端开发

    • Blade 模板
    • 本地化
    • 前端脚手架
    • 编译资源
  • 安全

    • 身份认证
    • API 身份认证
    • 授权
    • 邮件验证
    • 加密
    • 哈希
    • 重置密码
  • 深入话题

    • Artisan 命令行
    • 广播
    • 缓存
    • 集合
    • 事件
    • 文件存储
    • 辅助函数
    • Mail
    • 消息通知
    • 扩展包开发
    • 队列
    • 任务调度
  • 数据库

    • 快速入门
    • 查询构造器
    • 分页
    • 数据库迁移
    • 数据填充
    • Redis
  • Eloquent ORM

    • 快速入门
    • 关联关系
    • Eloquent 集合
    • 修改器
    • API 资源
    • 序列化
  • 测试

    • 快速入门
    • HTTP 测试
    • 命令行测试
    • 浏览器测试
    • 数据库测试
    • 测试模拟器Mocking
  • 官方扩展包

    • Cashier
    • Dusk浏览器测试
    • Envoy部署工具
    • Horizon队列管理工具
    • Passport OAuth 认证
    • Scout全文搜索
    • Socialite社会化登录
    • Telescope 调试工具
Icon

提示 您正在浏览旧版本的 Laravel 的文档. 请考虑将你的项目升级到 Laravel 11.x.

0 0

数据库测试
5.8
8.x 7.x 6.x 5.8 5.7 5.6 5.5 5.4 5.3 5.2 5.1

Laravel 5.8 中文文档 /

未匹配的标注
本文档最新版为 8.x,旧版本可能放弃维护,推荐阅读最新版!

Database Testing

  • 简介
  • 生成模型工厂
  • 每次测试后重置数据库
  • 写作工厂
    • 工厂状态
    • 工厂回调
  • 在测试中使用模型工厂
    • 创建模型
    • 持久化模型
    • 模型关联
  • 可用的断言方法

简介

Laravel 提供了各种有用的工具,可以更轻松地测试数据库驱动的应用程序。 首先,您可以使用 assertDatabaseHas 帮助程序断言数据库中存在的数据与给定的一组条件匹配。 例如,如果您要验证 users 表中的记录是否具有 sally @ example.com 的 email 值,您可以执行以下操作:

public function testDatabase()
{
    // Make call to application...

    $this->assertDatabaseHas('users', [
        'email' => 'sally@example.com'
    ]);
}

您还可以使用 assertDatabaseMissing 帮助程序断言数据库中不存在数据。

assertDatabaseHas 方法和其他类似的帮助程序是为了方便起见。 您可以自由使用任何 PHPUnit 的内置断言方法来补充您的测试。

生成模型工厂

使用 make:factory Artisan command 命令可以创建一个模型工厂:

php artisan make:factory PostFactory

新生成的工厂位置在 database/factories 目录下。

--model 选项可用于指示工厂创建的模型的名称。 此选项将使用给定模型预填充生成的工厂文件:

php artisan make:factory PostFactory --model=Post

每次测试后重置数据库

在每次测试后重置数据库通常很有用,这样前一次测试的数据不会干扰后续测试。 RefreshDatabase 特征采用最优化的方法来迁移测试数据库,具体取决于您使用的是内存数据库还是传统数据库。 在测试类上使用特征,一切都将为您处理:

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

    /**
     * 一个基本功能测试示例
     *
     * @return void
     */
    public function testBasicExample()
    {
        $response = $this->get('/');

        // ...
    }
}

创建模型工厂

测试时,您可能需要在执行测试之前将几条记录插入数据库。 在创建此测试数据时, Laravel 不是手动指定每列的值,而是允许您使用模型工厂为每个 Eloquent模型 定义一组默认属性。 开始测试前,请查看应用程序中的 database / factories / UserFactory.php 文件。 开箱即用,此文件包含一个工厂定义:

use Illuminate\Support\Str;
use Faker\Generator as Faker;

$factory->define(App\User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
        'remember_token' => Str::random(10),
    ];
});

在用作工厂定义的 Closure 中,您可以返回模型上所有属性的默认测试值。 Closure 将收到 Faker PHP 库的一个实例,它允许您方便地生成各种随机数据以进行测试。

您还可以为每个模型创建其他工厂文件,以便更好地进行组织。 例如,您可以在 database / factories 目录中创建 UserFactory.php 和 CommentFactory.php 文件。 factories 目录中的所有文件都将由 Laravel 自动加载。

您可以通过在 config / app.php 配置文件中添加 faker_locale 选项来设置 Faker 的语言环境。

工厂状态

States 允许您定义可以任意组合应用于模型工厂的离散修改。 例如,您的 User模型可能具有 deinquent 状态,可以修改其默认属性值之一。 您可以使用 state 方法定义状态转换。 对于简单状态,您可以传递一组属性修改:

$factory->state(App\User::class, 'delinquent', [
    'account_status' => 'delinquent',
]);

如果你的状态需要计算或 $ faker 实例,你可以使用 Closure 来计算状态的属性修改:

$factory->state(App\User::class, 'address', function ($faker) {
    return [
        'address' => $faker->address,
    ];
});

工厂回调

使用 afterMaking 和 afterCreating 方法注册工厂回调,并允许您在创建或创建模型后执行其他任务。 例如,您可以使用回调将其他模型与创建的模型相关联:

$factory->afterMaking(App\User::class, function ($user, $faker) {
    // ...
});

$factory->afterCreating(App\User::class, function ($user, $faker) {
    $user->accounts()->save(factory(App\Account::class)->make());
});

您还可以为 工厂状态 定义回调:

$factory->afterMakingState(App\User::class, 'delinquent', function ($user, $faker) {
    // ...
});

$factory->afterCreatingState(App\User::class, 'delinquent', function ($user, $faker) {
    // ...
});

使用模型工厂

创建模型

模型工厂定义后,就可以在测试或种子文件中使用全局 factory 函数来生成模型实例。 那么,让我们来看一些创建模型的例子。 首先,我们将使用 make 方法创建模型,但不将它们保存到数据库中:

public function testDatabase()
{
    $user = factory(App\User::class)->make();

    //在测试中使用模型...
}

您还可以创建许多模型的集合或创建给定类型的模型:

//创建三个 App\User 实例...
$users = factory(App\User::class, 3)->make();

应用状态

您也可以将任何 states 应用于模型。 如果要将多个状态转换应用于模型,则应指定要应用的每个状态的名称:

$users = factory(App\User::class, 5)->states('delinquent')->make();

$users = factory(App\User::class, 5)->states('premium', 'delinquent')->make();

覆盖属性

如果要覆盖模型的某些默认值,可以将一组值传递给 make 方法。 只有指定的值才会被替换,而其余值仍然设置为工厂指定的默认值:

$user = factory(App\User::class)->make([
    'name' => 'Abigail',
]);

持久化模型

create 方法不仅创建了模型实例,还使用Eloquent的 save 方法将它们保存到数据库中:

public function testDatabase()
{
    // 创建单个 App\User 实例...
    $user = factory(App\User::class)->create();

    // 创建3个 App\User 实例..
    $users = factory(App\User::class, 3)->create();

    // 在测试中使用模型...
}

您可以通过将数组传递给 create 方法来覆盖模型上的属性:

$user = factory(App\User::class)->create([
    'name' => 'Abigail',
]);

关联

在这个例子中,我们将附加一些创建模型的关系。 当使用 create 方法创建多个模型时,返回一个 Eloquent 集合实例 ,这样就可以在集合上使用 each 等便利方法:

$users = factory(App\User::class, 3)
           ->create()
           ->each(function ($user) {
                $user->posts()->save(factory(App\Post::class)->make());
            });

关联 & 属性闭包

您还可以使用工厂定义中的 Closure 属性将关系附加到模型。 例如,如果您想在创建 Post 时创建一个新的 User 实例,您可以执行以下操作:

$factory->define(App\Post::class, function ($faker) {
    return [
        'title' => $faker->title,
        'content' => $faker->paragraph,
        'user_id' => function () {
            return factory(App\User::class)->create()->id;
        }
    ];
});

这些闭包接收一个包含工厂属性的数组:

$factory->define(App\Post::class, function ($faker) {
    return [
        'title' => $faker->title,
        'content' => $faker->paragraph,
        'user_id' => function () {
            return factory(App\User::class)->create()->id;
        },
        'user_type' => function (array $post) {
            return App\User::find($post['user_id'])->type;
        }
    ];
});

可用的断言方法

Laravel 为 PHPUnit 测试提供了多个数据库断言方法:

方法 描述
$this->assertDatabaseHas($table, array $data); 断言数据库表中包含给定的数据。
$this->assertDatabaseMissing($table, array $data); 断言数据库表中不包含给定的数据。
$this->assertSoftDeleted($table, array $data); 断言数据库中的指定记录已软删除。

本文章首发在 网站上。


上一篇 下一篇

成为Laravel合作伙伴

Laravel Partners是提供一流Laravel开发和咨询服务的精英商店。我们每个合作伙伴都可以帮助您制定一个精美,结构完善的项目.

我们的伙伴
Laravel
亮点
  • Our Team
  • 发布说明
  • 入门
  • 路由
  • Blade 模板
  • 身份验证
  • 用户授权
  • Artisan 控制台
  • 数据库
  • Eloquent ORM
  • 测试
资源
  • Laravel Bootcamp
  • Laracasts
  • Laravel News
  • Laracon
  • Laracon EU
  • Laracon India
  • Jobs
  • Forums
  • Trademark
  • 版本发布时间
  • 包开发
  • 命令行应用
  • TALL stack全栈开发
  • Blade UI Kit
  • 前端资源构建
伙伴
  • WebReinvent
  • Vehikl
  • Tighten
  • 64 Robots
  • Active Logic
  • Byte 5
  • Curotec
  • Cyber-Duck
  • DevSquad
  • Jump24
  • Kirschbaum
生态系统
  • Cashier
  • Dusk
  • Echo
  • Envoyer
  • Forge
  • Horizon
  • Nova
  • Octane
  • Sail
  • Sanctum
  • Scout
  • Spark
  • Telescope
  • Valet
  • Vapor

Laravel是一个具有表达力,优雅语法的Web应用程序框架。我们认为,发展必须是一种令人愉悦的创造力,才能真正实现。Laravel试图通过减轻大多数Web项目中使用的常见任务来减轻开发的痛苦.

Laravel是Taylor Otwell的商标.
Copyright © 2011-2025 Laravel中文网 LLC.

  • Twitter
  • GitHub
  • Discord
Laravel 全栈开发网 推荐使用阿里云 按Ctrl+D试试