Is there a way to call artisan commands before my entire test suite? Installing Cartalyst extensions takes time so I do not want to do it before every test but I am presuming i cannot call facades from a static method like setUpBeforeClass, I receive this error
RuntimeException: A facade root has not been set. in /Users/lance/Desktop/FastLMS/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:218
<?php
namespace Tests;
use Illuminate\Contracts\Console\Kernel;
use Illuminate\Support\Facades\Artisan;
class TestCase extends \Illuminate\Foundation\Testing\TestCase
{
public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
Artisan::call('migrate');
Artisan::call('extension:install');
Artisan::call('extension:enable');
}
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
Hash::setRounds(4);
return $app;
}
public function setUp()
{
parent::setUp();
$this->app['Illuminate\Contracts\Http\Kernel']->disableMiddleware();
}
}
Related
I am trying to be able to load seed data inside of a Laravel test case but I keep encountering the error below.
<?php
namespace Tests\Feature;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class MagicTest extends TestCase
{
protected function setUp(): void
{
Artisan::call('db:seed');
}
public function test_show()
{
echo 'hi';
}
}
But when I try by running php artisan test
RuntimeException
A facade root has not been set.
at vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:334
How can I make this work? Or should I be taking a completely different approach?
When executing tests separately I have added this functions to make sure sqlite db would be created if it's not there:
abstract class TestCase extends BaseTestCase
{
use CreatesApplication, DatabaseMigrations;
public function setUp(): void
{
$this->initializeTestDB();
parent::setUp();
Notification::fake();
if ($this->tenancy) {
$this->initializeTenancy();
}
}
public function initializeTestDB(): void
{
$dbname = env('DB_DATABASE');
$filePath= "./" . $dbname;
if (!file_exists($filePath)) {
touch($filePath);
}
}
But this does not help when using php artisan test --parallel. I have tried to move this method into AppServiceProvider as in the documentation. Also didn't helped:
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
ParallelTesting::setUpProcess(function ($token) {
$this->handleTestDB();
});
Any ideas to handle this properly for both parallel and separate tests ?
I have problem with PHPUnit testing and Laravel
Exception: Class 'DB' not found
My TestCase file:
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
}
My CreatesApplication file:
namespace Tests;
use Illuminate\Contracts\Console\Kernel;
trait CreatesApplication
{
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
return $app;
}
}
This is my Test:
namespace Tests\Unit;
use App\Services\RepetitionService;
use PHPUnit\Framework\TestCase;
class RepetitionServiceTest extends TestCase
{
public function testGetNextIteration()
{
$repetitionService = new RepetitionService;
$nextIteration = $repetitionService->getNextIteration(1);
$this->assertEquals(2, $nextIteration);
}
}
Method that is being tested:
public function getNextIteration(int $lastIteration) : int
{
// some example code (method is not real but code below copied from original method)
\DB::table('cards')->get();
Config::get('params.repeat_iterations');
config('params.repeat_iterations');
}
Commend:
php vendor/phpunit/phpunit/phpunit --configuration phpunit.xml tests/Unit
Versions:
laravel 7
PHP 7.4
PHPUnit 9
Try to use DB from this path
use Illuminate\Support\Facades\DB;
I have service provider:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class InvitationServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* #return void
*/
public function register()
{
$this->app->bind('App\Service\InvitationServiceInterface', 'App\Service\InvitationService');
}
/**
* Bootstrap services.
*
* #return void
*/
public function boot()
{
//
}
}
Also there is an custom interface InvitationServiceInterface and InvitationService:
<?php
namespace App\Service;
class InvitationService implements InvitationServiceInterface
{
public function doAwesomeThing()
{
echo 'Do...';
}
}
Interface is:
<?php
namespace App\Service;
interface InvitationServiceInterface
{
public function doAwesomeThing();
}
These both files are place in path:
App\Service\InvitationServiceInterface
App\Service\InvitationService
So, I get an error:
Illuminate \ Contracts \ Container \ BindingResolutionException Target
[App\Service\InvitationServiceInterface] is not instantiable.
Using is:
use App\Service\InvitationServiceInterface;
use App\User;
use Illuminate\Http\Request;
class PassportController extends Controller
{
public function register(Request $request, InvitationServiceInterface $invitationService)
{
}
You can use the laravel service container in the constructor of a controller, i.e.:
class PassportController extends Controller
{
public function _construct(InvitationServiceInterface $invitationService)
{
$this->invitationService = $invitationService;
}
}
But not in a route controller function like you tried because here is the area of the route model binding so the service container is trying to instanciate a route model.
Probably service provider was cached.
Try to delete those two files:
Or run
php artisan config:clear
Or delete them derectry
rm bootstrap/cache/packages.php
rm bootstrap/cache/services.php
I am trying to write an integration test for my db seeder, but it does not seem to be returning an instance of that seeder. so it fails to execute
when i debug it the $adminUserSeeder is showing the following
this is my test
namespace Tests\Unit\user;
use AdminUserSeeder;
use App\Test;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use PHPUnit\Framework\TestCase;
class AdminSeederTest extends TestCase
{
use DatabaseTransactions;
public function setUp()
{
parent::setUp();
}
public function testRun()
{
$adminUserSeeder = new AdminUserSeeder();
$adminUserSeeder->run();
$this->assertDatabaseHas('users', ['name' => 'admin']);
}
}
and this is my seeder class
use Illuminate\Database\Seeder;
class AdminUserSeeder extends Seeder
{
public function run()
{
$user = (new App\User)->where('name','admin')->first();
if($user)
{
$user->delete();
}
factory(App\User::class,'admin')->create();
}
}
added the stack trace
/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1138
/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1104
/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:936
/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:880
/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:843
/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1477
/database/seeds/AdminUserSeeder.php:10
/tests/Unit/AdminSeederTest.php:21