Why doesn't PHPUnit see Laravel Facades? - laravel

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;

Related

Laravel - Test with Artisan seed fails

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?

How can I extend Laravel Dusk Browser?

I wish to override \Laravel\Dusk\Browser methods and extend it with my own, plus a few enhancements. Here is what I did so far but it gives me this error:
TypeError: Argument 1 passed to Tests\Browser\SequentialAppTest::Tests\Browser{closure}() must be an instance of Tests\MyBrowser, instance of Laravel\Dusk\Browser given,
called in
/var/www/gtest/vendor/laravel/dusk/src/Concerns/ProvidesBrowser.php on
line 67
/var/www/gtest/tests/Browser/SequentialAppTest.php:135
/var/www/gtest/vendor/laravel/dusk/src/Concerns/ProvidesBrowser.php:67
/var/www/gtest/tests/Browser/SequentialAppTest.php:157
file: tests/MyBrowser.php
<?php
namespace Tests;
class MyBrowser extends \Laravel\Dusk\Browser
{
}
file: tests/Browser/SequentialAppTest.php
namespace Tests\Browser;
use Tests\DuskTestCase;
use Tests\MyBrowser as Browser;
...
class SequentialAppTest extends DuskTestCase
{
....
}
Override newBrowser() in your test or in DuskTestCase:
use Tests\DuskTestCase;
use Tests\MyBrowser as Browser;
class SequentialAppTest extends DuskTestCase
{
protected function newBrowser($driver)
{
return new Browser($driver);
}
}

Laravel Testing/phpunit, Too few arguments passed when using dependency injection

I'm trying to create a simple test with Laravel. My test code is as below;
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Http\Controllers\Abc\AbcController;
class AbcTest extends TestCase
{
/**
* A basic test example.
*
* #return void
*/
private $abcController;
public function __construct (AbcController $abcController) {
$this->abcController = $abcController;
}
public function testExample()
{
$this->assertTrue(true);
}
However, when i run the test, i'm hitting this error,
PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function Tests\Feature\abc::__construct(), 0 passed in /var/www/nex/backend/vendor/phpunit/phpunit/src/Framework/TestSuite.php on line 151 and exactly 1 expected in /var/www/nex/backend/tests/Feature/abc.php:28
I've been using this method of performing dependency injections for the rest of my project. I'm not sure why its not working on this particular code.
All help is appreciated.
Thanks!
Check https://laravel.com/docs/5.8/testing you should not use Dependency Injection on controller. Instead you should call the endpoint.
Example
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Http\Controllers\Abc\AbcController;
class AbcTest extends TestCase
{
public function testExample()
{
$response = $this->get('/url');
$response->assertOk();
}
}

cartalyst extensions' routes only set after first test

Please help I'm using Laravel 5.5 with Cartalyst Platform 7.0 and Phpunit 6.0. I have been trying a lot to install extensions in a testing environment but when the first test runs the extensions routes are not defined so the test returns 404. The second test and the rest of the tests pass because the routes now exist. If I echo(count(\Route::getRoutes())) the first test it is 11 and the rest it is 329.
TestCase
<?php
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Support\Facades\Artisan;
use Sentinel;
abstract class TestCase extends BaseTestCase
{
use TestData, CreatesApplication;
public function setUp()
{
parent::setUp();
$this->app['Illuminate\Contracts\Http\Kernel']->disableMiddleware();
Sentinel::getUserRepository()->setModel(\App\Models\User::class);
Sentinel::getPersistenceRepository()->setUsersModel(\App\Models\User::class);
$this->setUpDatabase();
}
protected function setUpDatabase()
{
Artisan::call('migrate');
Artisan::call('extension:install');
Artisan::call('extension:enable');
}
}

How can call artisan commands before Test:suite

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();
}
}

Resources