Reputation: 6071
I am trying to recreate the database before each test in some PHPUnit test cases. I am using Laravel 5.3. Here is TestCase:
class CourseTypesTest extends TestCase
{
public function setUp()
{
parent::setUp();
Artisan::call('migrate');
Artisan::call('db:seed', ['--class' => 'TestDatabaseSeeder ', '--database' => 'testing']);
}
/**
* A basic functional test example.
*
* @return void
*/
public function test_list_course_types()
{
$httpRequest = $this->json('GET', '/api/course-types');
$httpRequest->assertResponseOk();
$httpRequest->seeJson();
}
public function tearDown()
{
Artisan::call('migrate:reset');
parent::tearDown();
}
}
Running phpunit
fails with error:
$ phpunit PHPUnit 5.7.5 by Sebastian Bergmann and contributors.
E 1 / 1 (100%)
Time: 2.19 seconds, Memory: 12.00MB
There was 1 error:
1) CourseTypesTest::test_list_course_types ReflectionException: Class TestDatabaseSeeder does not exist
D:\www\learn-laravel\my-folder-api\vendor\laravel\framework\src\Illuminate\Container\Container.php:749 D:\www\learn-laravel\my-folder-api\vendor\laravel\framework\src\Illuminate\Container\Container.php:644 D:\www\learn-laravel\my-folder-api\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:709 D:\www\learn-laravel\my-folder-api\vendor\laravel\framework\src\Illuminate\Database\Console\Seeds\SeedCommand.php:74 D:\www\learn-laravel\my-folder-api\vendor\laravel\framework\src\Illuminate\Database\Console\Seeds\SeedCommand.php:63 D:\www\learn-laravel\my-folder-api\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php:2292 D:\www\learn-laravel\my-folder-api\vendor\laravel\framework\src\Illuminate\Database\Console\Seeds\SeedCommand.php:64 D:\www\learn-laravel\my-folder-api\vendor\laravel\framework\src\Illuminate\Container\Container.php:508 D:\www\learn-laravel\my-folder-api\vendor\laravel\framework\src\Illuminate\Console\Command.php:169 D:\www\learn-laravel\my-folder-api\vendor\symfony\console\Command\Command.php:254 D:\www\learn-laravel\my-folder-api\vendor\laravel\framework\src\Illuminate\Console\Command.php:155 D:\www\learn-laravel\my-folder-api\vendor\symfony\console\Application.php:821 D:\www\learn-laravel\my-folder-api\vendor\symfony\console\Application.php:187 D:\www\learn-laravel\my-folder-api\vendor\symfony\console\Application.php:118 D:\www\learn-laravel\my-folder-api\vendor\laravel\framework\src\Illuminate\Console\Application.php:107 D:\www\learn-laravel\my-folder-api\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php:218 D:\www\learn-laravel\my-folder-api\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:237 D:\www\learn-laravel\my-folder-api\tests\rest\CourseTypesTest.php:17
ERRORS! Tests: 1, Assertions: 0, Errors: 1.
Upvotes: 35
Views: 31966
Reputation: 21
For those stumbling on this question recently and are using a newer version of Laravel, ever since Laravel 8.0 there is a simpler way to do this.
If you use the Framework's provided base test case Illuminate\Foundation\Testing\TestCase
and you use any of the db traits, such as Illuminate\Foundation\Testing\RefreshDatabase
, you can just add a protected $seed = true;
property to your tests and it will seed the db when doing the migrations.
Example from the documentation:
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
abstract class TestCase extends BaseTestCase
{
use RefreshDatabase;
/**
* Indicates whether the default seeder should run before each test.
*
* @var bool
*/
protected $seed = true;
}
Upvotes: 1
Reputation: 431
Refresh your database with Artisan
:
Artisan::call('migrate:fresh --seed');
This command removes your tables, creates the tables again (runs the migrations) and then seeds the tables with clean data.
Upvotes: 0
Reputation: 45
You can try this way. You can execute this command when you run your test.
Upvotes: -3
Reputation: 2295
Since version 5.8 you can do:
// Run the DatabaseSeeder...
$this->seed();
// Run a single seeder...
$this->seed(OrderStatusesTableSeeder::class);
Take a look at the documentation
Upvotes: 40
Reputation: 814
The problem is empty space in your --class argument. If you take close look at array '--class' => 'TestDatabaseSeeder '
there is space in the end ... this is the problem. Change it to '--class' => 'TestDatabaseSeeder'
and it should work fine.
Upvotes: 13
Reputation: 465
The DatabaseSeeder
can be instantiated on its own, and its call
method is public.
All you need to do in your CourseTypesTest
class would be
(new DatabaseSeeder())->call(TestDatabaseSeeder::class);
Or you can make use of Laravel's app
helper as follow
app(DatabaseSeeder::class)->call(TestDatabaseSeeder::class);
Upvotes: 22