This directory contains comprehensive unit and feature tests for the LaraUtilX package.
tests/
├── TestCase.php # Base test case with Laravel setup
├── Unit/ # Unit tests for individual components
│ ├── Console/
│ │ └── MakeCrudCommandTest.php
│ ├── Enums/
│ │ └── LogLevelTest.php
│ ├── Rules/
│ │ └── RejectCommonPasswordsTest.php
│ ├── Traits/
│ │ ├── ApiResponseTraitTest.php
│ │ ├── AuditableTest.php
│ │ └── FileProcessingTraitTest.php
│ └── Utilities/
│ ├── CachingUtilTest.php
│ ├── ConfigUtilTest.php
│ ├── FeatureToggleUtilTest.php
│ ├── FilteringUtilTest.php
│ ├── LoggingUtilTest.php
│ ├── PaginationUtilTest.php
│ ├── QueryParameterUtilTest.php
│ ├── RateLimiterUtilTest.php
│ └── SchedulerUtilTest.php
└── Feature/ # Integration tests
├── Http/
│ └── Controllers/
│ └── CrudControllerTest.php
└── Traits/
└── ApiResponseTraitFeatureTest.php
The suite contains 245 tests as of v1.5.5, and runs in CI against Laravel 10, 11, 12, and 13 on every push and pull request.
Make sure you have installed the development dependencies:
composer install --dev
./vendor/bin/phpunit
# Run only unit tests
./vendor/bin/phpunit --testsuite Unit
# Run only feature tests
./vendor/bin/phpunit --testsuite Feature
# Run tests for a specific utility
./vendor/bin/phpunit tests/Unit/Utilities/CachingUtilTest.php
# Run tests for a specific trait
./vendor/bin/phpunit tests/Unit/Traits/ApiResponseTraitTest.php
./vendor/bin/phpunit --coverage-html coverage
The test suite provides comprehensive coverage for:
When adding new functionality to LaraUtilX, follow these guidelines:
The test suite is designed to run in CI environments with:
<?php
namespace LaraUtilX\Tests\Unit\Utilities;
use LaraUtilX\Tests\TestCase;
use LaraUtilX\Utilities\ConfigUtil;
use Illuminate\Support\Facades\Storage;
class ConfigUtilTest extends TestCase
{
private ConfigUtil $configUtil;
protected function setUp(): void
{
parent::setUp();
$this->configUtil = new ConfigUtil();
}
public function test_can_get_all_app_settings()
{
$settings = $this->configUtil->getAllAppSettings();
$this->assertIsArray($settings);
$this->assertArrayHasKey('name', $settings);
$this->assertArrayHasKey('env', $settings);
}
public function test_can_get_setting_from_existing_file()
{
// Create a test settings file
$testSettings = ['test_key' => 'test_value', 'another_key' => 'another_value'];
$filePath = 'test_settings.json';
Storage::put($filePath, json_encode($testSettings));
$settings = $this->configUtil->getAllSettings($filePath);
$this->assertEquals($testSettings, $settings);
// Clean up
Storage::delete($filePath);
}
public function test_returns_empty_array_for_non_existent_file()
{
$settings = $this->configUtil->getAllSettings('non_existent_file.json');
$this->assertEquals([], $settings);
}
}
<?php
namespace LaraUtilX\Tests\Feature\Traits;
use LaraUtilX\Tests\TestCase;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Config;
class ApiResponseTraitFeatureTest extends TestCase
{
use \LaraUtilX\Traits\ApiResponseTrait;
public function test_success_response_integration()
{
$data = [
'users' => [
['id' => 1, 'name' => 'John Doe'],
['id' => 2, 'name' => 'Jane Smith'],
],
];
$message = 'Users retrieved successfully';
$meta = [
'total' => 2,
'page' => 1,
];
$response = $this->successResponse($data, $message, 200, $meta);
$this->assertInstanceOf(JsonResponse::class, $response);
$this->assertEquals(200, $response->getStatusCode());
$responseData = $response->getData(true);
$this->assertTrue($responseData['success']);
$this->assertEquals($message, $responseData['message']);
$this->assertEquals($data, $responseData['data']);
$this->assertEquals($meta, $responseData['meta']);
}
public function test_paginated_response_integration()
{
// Create a mock paginator with realistic data
$items = collect(range(1, 25))->map(function ($i) {
return [
'id' => $i,
'name' => "Item {$i}",
'created_at' => now()->subDays($i)->toDateTimeString(),
];
});
$paginator = new LengthAwarePaginator(
$items->forPage(1, 10),
25,
10,
1,
['path' => '/api/items']
);
$response = $this->paginatedResponse($paginator, 'Items retrieved successfully');
$this->assertInstanceOf(JsonResponse::class, $response);
$this->assertEquals(200, $response->getStatusCode());
$responseData = $response->getData(true);
$this->assertTrue($responseData['success']);
$this->assertEquals('Items retrieved successfully', $responseData['message']);
$this->assertCount(10, $responseData['data']);
$this->assertArrayHasKey('pagination', $responseData['meta']);
}
}
Database Connection Issues
Cache Issues
File System Issues
--verbose flag for detailed outputdd() or dump() for debugging--stop-on-failure to debug specific testsWhen contributing to the test suite:
The suite runs in GitHub Actions on every push and pull request, across the full support matrix:
| Laravel | PHP | Testbench |
|---|---|---|
| 10 | 8.1 | ^8.37 |
| 11 | 8.2 | ^9.0 |
| 12 | 8.3 | ^10.0 |
| 13 | 8.4 | ^11.0 |
Laravel 10 runs on PHP 8.1 so the package's declared floor is exercised rather than assumed.
Each row runs the suite twice, once in declaration order and once with --order-by=random, because order-dependent tests pass reliably in declaration order and fail intermittently everywhere else.
Laravel 10 and 11 are end of life and every release carries an unpatched advisory, so those two rows set composer config audit.block-insecure false. Without it Composer refuses to install them at all.