In this article will showing how excute a phpunit for SQLite in laravel.
In here should prepare mysql and setting .env for database info.
First, create a hello model and use the -m options for generate a migration file
php artisan make:model Hello --m
Just need add name column in hello_table migration file:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateHellosTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('hellos', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('hellos');
}
}
Excute artisan migrate command for generate table:
php artisan migrate
In here we make a repository for access Hello model, and HelloService will access HelloRepository, and HelloControler.
Also, generate service and repository test.
php artisan make:controller ../Repositorys/HelloRepository
php artisan make:controller ../Services/HelloServices
php artisan make:controller HelloController
php artisan make:test HelloServiceTest
php artisan make:test HelloRepositorytest
Prepare seeder for unittest:
php artisan make:seeder HelloSeeder
HelloSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Hello;
class HelloSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$hello = new Hello;
$hello->name = 'hello-unittest';
$results = $hello->save();
}
}
Add HelloSeeder to DatabaseSeeder caller:
DatabaseSeeder.php
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call([
HelloSeeder::class,
]);
}
}
SQLite for unittest
Mac has include SQLite in environment:
sqlite3
In here, we need use sqlite for unittest.
First, setting .env.testing as fellowing:
.env.testing
DB_CONNECTION=sqlite
DB_DATABASE=':memory:
Second, setting phpunit.xml, open sqlite and database information:
phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
>
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./app</directory>
</include>
</coverage>
<php>
<server name="APP_ENV" value="testing"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="DB_CONNECTION" value="sqlite"/>
<server name="DB_DATABASE" value="database/database.sqlite"/>
<server name="MAIL_MAILER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="TELESCOPE_ENABLED" value="false"/>
</php>
</phpunit>
Setting database config, add sqlite
config/database.php
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
create database.sqlite
touch database/database.sqlite
Prepare TestCase for sqlite
tests/TestCase.php
<?php
declare(strict_types=1);
namespace Tests;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
protected function initDatabase()
{
Artisan::call('migrate');
Artisan::call('db:seed --class=HelloSeeder');
}
protected function resetDatabase()
{
Artisan::call('migrate:reset');
}
}
tests/Feature/HelloRepositoryTest.php
<?php
namespace Tests\Feature;
use App\Models\Hello;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
class HelloRepositorytestTest extends TestCase
{
use RefreshDatabase;
public function setUp(): void
{
parent::setUp();
$this->initDatabase();
}
public function tearDown(): void
{
$this->resetDatabase();
parent::tearDown();
}
/**
* test create data
* @return void
*/
public function testCreateData()
{
$hello = new Hello;
$hello->name = 'hihi';
$condition = $hello->save();
$this->asserttrue($condition);
$expected = 'hihi';
$actual = $hello->name;
$this->assertsame($expected, $actual);
}
/**
* test query data
* @return void
*/
public function testQueryData()
{
$hello = Hello::query()
->first();
$expected = 'hello-unittest';
$actual = $hello->name;
$this->assertsame($expected, $actual);
}
}
Run your test
sqlite3 database/database.sqlite
sqlite>.tables
hellos migrations
sqlite> select * from migrations;
1|2021_06_07_234357_create_hellos_table|1
test controller
HelloController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Services\HelloServices;
class HelloController extends Controller
{
protected $HelloServices;
public function __construct(HelloServices $HelloServices) {
$this->HelloServices = $HelloServices;
}
public function get() {
$result = $this->HelloServices->get();
return $result;
}
public function update(Request $request):bool {
$id = $request->id;
$name = $request->name;
$result = $this->HelloServices->updateOne(['id'=>$id, 'name'=>$name]);
return $result;
}
public function create(Request $request):bool {
$name = $request->name;
$result = $this->HelloServices->addOne($name);
return $result;
}
}
api.php
Route::get('/hellos', [HelloController::class, 'get'] );
Route::post('/hellos/update', [HelloController::class, 'update'] );
Route::post('/hellos/create', [HelloController::class, 'create'] );
HelloServices.php
<?php
namespace App\Http\Services;
use App\Http\Repositorys\HelloRepository;
use Illuminate\Database\Eloquent\Collection;
class HelloServices
{
protected $HelloRepository;
/**
* @param App\Http\Repositorys\HelloRepository $HelloRepository
*/
public function __construct(HelloRepository $HelloRepository) {
$this->HelloRepository = $HelloRepository;
}
public function get():Collection {
return $this->HelloRepository->fetchHello();
}
public function addOne(string $name):bool {
return $this->HelloRepository->createHello($name);
}
public function updateOne(array $data):bool {
return $this->HelloRepository->updateHello($data);
}
}
Write create and update data for controller
HelloController.php
<?php
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\Hello;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class HelloControllerTest extends TestCase
{
use RefreshDatabase;
/**
* Test hello contoller add one
*
* @return void
*/
public function testHelloControllerAddOne()
{
$response = $this->post('/api/hellos/create', ['name'=>'halo']);
$response->assertStatus(200);
$hello = Hello::query()
->where('name', 'halo')
->first();
$expected = 'halo';
$actual = $hello->name;
$this->assertsame($expected, $actual);
}
/**
* Test hello contoller update one
*
* @return void
*/
public function testHelloControllerUpdateOne()
{
$hello = new Hello;
$hello->name = 'this is test add one';
$hello->save();
$id = $hello->id;
$response = $this->post('/api/hellos/update', ['id'=>$id, 'name'=>'this is test update one']);
$response->assertStatus(200);
$hello = Hello::query()
->where('id', $id)
->first();
$expected = 'this is test update one';
$actual = $hello->name;
$this->assertsame($expected, $actual);
}
/**
* Test hello contoller get data
*
* @return void
*/
public function testHelloControllerFetchData()
{
$hello = new Hello;
$hello->name = 'this is test add one';
$hello->save();
$id = $hello->id;
$response = $this->get('/api/hellos');
$response->assertStatus(200);
$response->assertSeeText('this is test add one', $escaped = true);
$this->assertEquals('this is test add one', $response[0]['name']);
}
/**
* Test hello contoller get data2
*
* @return void
*/
public function testHelloControllerFetchData2()
{
$response = $this->get('/api/hellos');
$response->assertStatus(200);
}
}