Testovanie
Posts::fake() nasadí za fasádu aj do kontajnera zaznamenávajúci fake — rozširuje PostsManager, takže ho dostanú aj vložené manažéry. Každý zápis — cez fasádu, vložený manažér, builder, metódy cyklu na modeli a syncTags(), listener moderácie či posts:publish-scheduled — sa namiesto vykonania len zaznamená: nič sa nezapíše a nespustí sa žiadna udalosť. create() vráti neuložený príspevok naplnený tak, ako by to urobila akcia; ostatné zápisy vrátia príspevok nezmenený a publishDue() vráti 0. Čítania — findBySlug(), published(), query() — stále idú do databázy:
use RoundlyConsulting\Posts\DataTransferObjects\CreatePostData;
use RoundlyConsulting\Posts\DataTransferObjects\SeoData;
use RoundlyConsulting\Posts\Facades\Posts;
Posts::fake();
// … exercise your code …
Posts::assertCreated(fn (CreatePostData $data): bool => $data->translations[0]->title === 'Hello');
Posts::assertPublished($post); // optionally: Posts::assertPublished($post, $at)
Posts::assertScheduled($post, $at);
Posts::assertArchived($post);
Posts::assertUnpublished($post);
Posts::assertSeoUpdated($post, fn (SeoData $seo): bool => $seo->robots === 'noindex');
Posts::assertTagged($post, ['laravel', 'php']);
Posts::assertPublishedDue();Asercie
Volajte ich na fasáde alebo na PostsFake, ktorý vráti Posts::fake(). Každá asercia má negatívny pár:
| Asercia | Negatívny pár | Prejde, keď |
|---|---|---|
assertCreated(fn (CreatePostData $d) => …) | assertNothingCreated() | Zaznamenalo sa vytvorenie (zodpovedajúce callbacku). |
assertPublished($post, ?$at) | assertNothingPublished() | Príspevok bol publikovaný (k danému $at; bez neho s akýmkoľvek dátumom či bez neho). |
assertScheduled($post, ?$at) | assertNothingScheduled() | Príspevok bol naplánovaný (na daný $at). |
assertArchived($post) | assertNothingArchived() | Príspevok bol archivovaný. |
assertUnpublished($post) | assertNothingUnpublished() | Príspevok sa vrátil do konceptu. |
assertSeoUpdated($post, fn (SeoData $s) => …) | assertNothingSeoUpdated() | SEO príspevku sa zmenilo (podľa callbacku). |
assertTagged($post, ['laravel', 'php']) | assertNothingTagged() | Tagy sa synchronizovali — pri zadaní presne na tieto názvy; modely Tag sa porovnajú podľa názvu v aktuálnom jazyku. |
assertPublishedDue() | assertNothingPublishedDue() | Prebehlo publishDue() — cez fasádu, manažér alebo príkaz. |
Príspevky sa porovnávajú podľa identity, alebo — ak sú oba uložené — cez is(); dva neuložené príspevky sa nikdy nezhodujú.
use App\Models\User;
use RoundlyConsulting\Posts\Facades\Posts;
use RoundlyConsulting\Posts\Models\Post;
it('publishes a post from the admin', function () {
$fake = Posts::fake(); // returns the PostsFake
$post = Post::factory()->create();
$this->actingAs(User::factory()->create())
->post(route('admin.posts.publish', $post))
->assertRedirect();
$fake->assertPublished($post);
$fake->assertNothingArchived();
$fake->assertNothingCreated();
});Factories
Balík obsahuje factories pre všetky tri modely; Post::factory() vytvára nakonfigurovaný model príspevku:
use RoundlyConsulting\Posts\Models\Category;
use RoundlyConsulting\Posts\Models\Post;
use RoundlyConsulting\Posts\Models\Tag;
Post::factory()->published()->forAuthor($user)->create(); // states: draft, published, scheduled (+1 day), archived
Post::factory()->withTitles(['en' => 'Hello', 'sk' => 'Ahoj'])->create();
Category::factory()->childOf($parent)->create();
Tag::factory()->create();Plánované publikovanie naozaj
Bez fake zmrazte čas, vytvorte príspevky v čase aj v budúcnosti, spustite príkaz a overte výsledok:
use Carbon\CarbonImmutable;
use Illuminate\Support\Facades\Event;
use RoundlyConsulting\Posts\Enums\PostStatus;
use RoundlyConsulting\Posts\Events\PostPublished;
use RoundlyConsulting\Posts\Models\Post;
it('publishes scheduled posts whose time has come', function () {
Event::fake([PostPublished::class]);
CarbonImmutable::setTestNow('2026-01-01 12:00:00');
$due = Post::factory()->create(['status' => PostStatus::Scheduled, 'published_at' => now()->subHour()]);
$future = Post::factory()->create(['status' => PostStatus::Scheduled, 'published_at' => now()->addHour()]);
$this->artisan('posts:publish-scheduled')->assertSuccessful();
expect($due->fresh()->status)->toBe(PostStatus::Published)
->and($future->fresh()->status)->toBe(PostStatus::Scheduled);
Event::assertDispatched(PostPublished::class);
});Médiá
Použite fake disk a fake upload — žiadne reálne súbory sa nedotknú úložiska:
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use RoundlyConsulting\Posts\Models\Post;
it('uses the featured image as og:image', function () {
Storage::fake('public');
$post = Post::factory()->create();
$post->addMedia(UploadedFile::fake()->image('hero.jpg', 800, 600))
->toMediaBucket($post->featuredBucket());
expect($post->seo()->ogImage)->toBe($post->featuredImageUrl())
->and($post->toJsonLd()['image'])->toBe($post->featuredImageUrl());
});Testy spúšťajte s publikovanými migráciami (RefreshDatabase). Pamätajte, že SQLite prijme uuid aj do bigint morph stĺpca, preto zmeny typov kľúčov testujte na engine, ktorý nasadzujete.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.