每当我分别运行它们时,我的测试都达到绿色状态,但是当我同时运行它们时,在第一次测试中都达到了SQLSTATE [23000]。第一个测试是我之前进行过的对应用程序有意义的测试,第二个是您可以看到的虚拟测试。
我已经恢复了错误消息,因为它显示了来自laravel的很多类,但是它指向第27行('user_id'=> 1)。
测试
<?php
namespace Tests\Unit;
use App\User;
use App\Tournament;
use Tests\TestCase;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class TournamentTest extends TestCase
{
/**
* A basic unit test example.
*
* @return void
*/
use RefreshDatabase;
protected function setUp() : void
{
parent::setUp();
$this->withoutExceptionHandling();
factory(User::class)->create();
factory(Tournament::class)->create([
'user_id' => 1
]);
}
/** @test **/
public function index_page_shows_tournaments()
{
$user = User::first();
$response = $this->actingAs($user)->get('/tournaments');
$response->assertViewIs('tournaments.index');
}
/** @test **/
public function create_tournament_shows_number_of_challengers()
{
$this->assertTrue(true);
}
}
错误
There was 1 error:
1) Tests\Unit\TournamentTest::create_tournament_shows_number_of_challengers
Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`torneio`.`tournaments`, CONSTRAINT `tournaments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)) (SQL: insert into `tournaments` (`user_id`, `name`, `interval`, `round`, `chal_num`, `status`, `updated_at`, `created_at`) values (1, Best Cross-group neutral support, 38, 1, 8, 1, 2019-05-09 00:56:44, 2019-05-09 00:56:44))
/home/tadeusvult/dev/torneio/tests/Unit/TournamentTest.php:27
Caused by
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`torneio`.`tournaments`, CONSTRAINT `tournaments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`))
答案 0 :(得分:0)
违反约束错误表明users
表中没有id = 1的行。 SELECT * FROM users WHERE id = 1
将返回空。
Laravel's document没有提及此行为-Rolling back a transaction will still increment the primary key。另请参见MySQL文档:“Lost” auto-increment values and sequence gaps。
setUp()
和use RefreshDatabase;
内部发生了什么:
protected function refreshTestDatabase()
{
if (! RefreshDatabaseState::$migrated) {
$this->artisan('migrate:fresh', ...);
...
RefreshDatabaseState::$migrated = true;
}
$this->beginDatabaseTransaction();
}
TournamentTest
启动时,users
将重置migrate:fresh
表中的auto_increment,但不会在每种测试用例方法中重置。换句话说,当create_tournament_shows_number_of_challengers()
运行时,由于回滚,index_page_shows_tournaments()
中没有行,但是auto_increment仍返回2。
尝试打印出setUp()
中的ID。最好还是不要使用硬编码的号码:
protected function setUp() : void
{
parent::setUp();
$this->withoutExceptionHandling();
$user = factory(User::class)->create();
var_dump($user->id); // see what's going on
factory(Tournament::class)->create([
'user_id' => $user->id // clearer intention
]);
}