Laravel 5.5内存数据库单元测试报错:表不存在求助
在Laravel单元测试中正确使用内存数据库解决表不存在问题
看起来你遇到了内存数据库测试时表不存在的问题,这通常是迁移执行不彻底或者测试代码的小问题导致的,我来一步步帮你解决:
1. 排查核心问题根源
你收到的no such table: books错误,说明虽然配置了内存SQLite,但迁移脚本没有在测试开始时创建对应的表。另外你的测试代码里还有一个小错误需要修正。
2. 修正测试类的Trait使用
把DatabaseMigrations替换为RefreshDatabase trait,这个trait是Laravel专门为测试设计的,它会在每个测试开始时自动运行所有迁移,测试结束后清理数据库,对于内存SQLite来说适配性更好:
// 替换前 use Illuminate\Foundation\Testing\DatabaseMigrations; // 替换后 use Illuminate\Foundation\Testing\RefreshDatabase;
3. 修复测试代码中的查询错误
你代码里的$book->find(1)是错误的调用方式——find()是模型的静态方法或者查询构造器方法,不能直接在已创建的模型实例上这么用。可以直接断言创建好的模型属性,或者用模型类重新查询数据库:
修改后的完整测试代码:
<?php namespace Tests\Feature; use Tests\TestCase; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Foundation\Testing\RefreshDatabase; class BookTest extends TestCase { use RefreshDatabase; public function test_books_can_be_created() { $user = factory(\App\User::class)->create(); $book = $user->books()->create([ 'name' => 'The hobbit', 'price' => 10 ]); // 直接断言创建的模型属性(最简单的方式) $this->assertEquals('The hobbit', $book->name); $this->assertEquals(10, $book->price); // 可选:从数据库重新查询验证数据确实被存储 $foundBook = \App\Book::find($book->id); $this->assertNotNull($foundBook); $this->assertEquals('The hobbit', $foundBook->name); $this->assertEquals(10, $foundBook->price); } }
4. 确认迁移文件存在且正确
确保database/migrations目录下有创建books表的迁移文件,比如类似2024_05_20_000000_create_books_table.php的文件,里面要包含正确的表结构和外键关联:
示例迁移文件代码:
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up() { Schema::create('books', function (Blueprint $table) { $table->id(); $table->foreignId('user_id')->constrained(); $table->string('name'); $table->decimal('price', 8, 2); $table->timestamps(); }); } public function down() { Schema::dropIfExists('books'); } };
5. 确保环境配置无冲突
如果项目根目录存在.env.testing文件,确保里面的数据库配置和phpunit.xml一致,避免配置冲突:
APP_ENV=testing DB_CONNECTION=sqlite DB_DATABASE=:memory: CACHE_DRIVER=array SESSION_DRIVER=array QUEUE_DRIVER=sync
最后运行测试
现在执行vendor/bin/phpunit,你的测试应该能正常通过了——内存数据库会在每个测试开始时自动创建所有表,测试结束后销毁,保证每个测试都是独立干净的环境。
内容的提问来源于stack exchange,提问作者vimuth
相关产品推荐
相关产品推荐

