jac*_*414 8 phpunit laravel laravel-5
我有一个包含users表格的Laravel 5.3应用程序.该表上的一个字段是api_token,在数据库定义中设置为NOT NULL.如果我使用Postman并点击我的API端点来创建用户并且不包含该api_token字段,则会收到以下错误:SQLSTATE[HY000]: General error: 1364 Field 'api_token' doesn't have a default value.
我还没有添加代码来生成令牌,所以这正是我所期望的.但是,我有这个PHPUnit测试:
/** @test */
public function a_user_can_be_created()
{
$this->user_data = [
'first_name' => 'Jane',
'last_name' => 'Smith',
'email_address' => 'jsmith@mailinator.com',
'phone' => '1234567890',
'username' => 'jsmith',
'password' => 'testing'
];
$this->post('/api/users', $this->user_data, array(
'Accept' => 'application/json'
))
->assertResponseStatus(201)
->seeJsonEquals(['status' => 'success'])
->seeInDatabase('users', $this->user_data);
}
Run Code Online (Sandbox Code Playgroud)
问题是测试通过了.当用户保存数据库时应该抛出异常,该测试如何成功?
我已经在不同时间点"死亡并倾倒"并确认在自动化测试运行时数据实际上已保存到数据库中.我也尝试使用相同的数据库进行Postman和自动测试(而不是单独的测试数据库) - 相同的结果.
我尝试构建API的最小版本,并在最新的Laravel 5.3.22版本上创建类似的测试.我还使用MariaDB 10.1.13作为数据库.事实证明,由于空洞,测试失败了api_token.
这是我用于创建users表的迁移文件:
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('first_name');
$table->string('last_name');
$table->string('email_address')->unique();
$table->string('phone');
$table->string('username');
$table->string('password');
$table->string('api_token');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('users');
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的app\User.php文件看起来像.非常小,我只更新$fillable属性以匹配我们的users表结构:
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'first_name',
'last_name',
'email_address',
'phone',
'username',
'password',
'api_token',
];
protected $hidden = [
'password',
];
}
Run Code Online (Sandbox Code Playgroud)
我在routes/api.php文件上创建一个新的API路由来创建一个新用户.超级简单,无需任何验证:
Route::post('users', function (Request $request) {
$data = $request->only([
'first_name',
'last_name',
'email_address',
'phone',
'username',
'password',
'api_token',
]);
if (is_string($data['password'])) {
$data['password'] = bcrypt($data['password']);
}
$user = App\User::create($data);
return response()->json([
'status' => 'success',
], 201);
});
Run Code Online (Sandbox Code Playgroud)
最后这是我的测试文件,用于测试我们的创建用户API.
class ApiTest extends TestCase
{
/** @test */
public function a_user_can_be_created()
{
$user = [
'first_name' => 'Jane',
'last_name' => 'Smith',
'email_address' => 'jsmith@mailinator.com',
'phone' => '1234567890',
'username' => 'jsmith',
];
$this->json('POST', 'api/users', $user)
->assertResponseStatus(201)
->seeJsonEquals(['status' => 'success'])
->seeInDatabase('users', array_except($user, ['password']));
}
}
Run Code Online (Sandbox Code Playgroud)
唯一的区别是我array_except()以前password从数据库测试中排除了列,因为我们在将值存储到数据库之前对其进行了散列.但是,这当然与您的问题无关.
当我在没有api_token设置的情况下运行测试时,测试按预期失败.API返回状态代码500,而我们预计它是201.
另外作为参考,当我将api_token列设置为NOT nullable时,然后强制创建一个空的新用户,api_token我收到的异常消息是这样的:
Connection.php第769行中的QueryException:
SQLSTATE [23000]:完整性约束违规:1048列'api_token'不能为空(SQL:插入用户...
希望这有助于您调试问题!
您应该为表api_token中的列定义一个默认值users,或者应该将其设置为nullable,您的用户表迁移将如下所示:
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('api_token')->nullable();
// Or you can set it to default value - 0
// $table->string('api_token')->default('0');
$table->timestamps();
});
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
772 次 |
| 最近记录: |