NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky

Campaigns::fake() nasadí zaznamenávajúci fake za fasádu aj do kontajnera, takže ho vidia injektované manažéry, príkaz campaigns:cancel aj joby doručenia. Každý zápis namiesto vykonania zaznamená — žiadna dávka, žiadny job vo fronte, žiadna udalosť, nič sa nezapíše do nakonfigurovaného úložiska — a má vlastné úložisko v pamäti, takže find(), all() aj campaign()->progress() / recipients() odpovedajú z toho, čo test vytvoril:

use RoundlyConsulting\Campaigns\Campaign;
use RoundlyConsulting\Campaigns\Facades\Campaigns;

it('sends the spring sale to both subscribers', function (): void {
    $fake = Campaigns::fake();

    $campaign = Campaigns::create('Spring sale', '<p>The spring sale starts today.</p>')
        ->from('[email protected]', 'Example Shop')
        ->to(['[email protected]', '[email protected]'])
        ->dispatch();

    $fake->assertDispatched(fn (Campaign $campaign, array $recipients) => $campaign->subject === 'Spring sale'
        && count($recipients) === 2);
    $fake->assertStarted($campaign);
    $fake->assertNothingCancelled();

    // Answered from the fake's own in-memory store.
    expect(Campaigns::campaign($campaign)->recipients())->toHaveCount(2);
});
AserciaPrejde, keď
assertCreated(?Closure $callback) / assertNothingCreated()Kampaň bola pripravená — create()->prepare(), ->dispatch() alebo Campaigns::prepare(). Callback dostane Campaign a jej list<CampaignRecipient>.
assertDispatched(?Closure $callback) / assertNothingDispatched()Kampaň bola vytvorená a spustená.
assertStarted(Campaign|string|null $campaign) / assertNothingStarted()Prebehlo start() — priamo, cez handle alebo cez dispatch().
assertCancelled(Campaign|string|null $campaign) / assertNothingCancelled()Prebehlo cancel() — priamo, cez handle alebo z príkazu.
assertRecipientProcessed(CampaignRecipient|string|null $recipient) / assertNothingProcessed()Zaznamenalo sa doručenie — napríklad spustením handle() vášho jobu pod fake.
assertRecipientFailed(CampaignRecipient|string|null $recipient, ?string $error) / assertNothingFailed()Zaznamenalo sa neúspešné doručenie.

Každá asercia funguje aj staticky (Campaigns::assertCancelled($uuid)). Fake stále odmieta to, čo odmieta skutočný manažér: neznáme uuid, už obsadené uuid, spustenie kampane, ktorá nie je v stave Pending, a príjemcu inej kampane.

Testovanie jobu doručenia

Zostavte job z Campaign a CampaignRecipient, ktorý k nej patrí, a spracujte ho priamo. withFakeBatch() — z traitu Batchable v Laraveli — simuluje beh vnútri dávky, aj zrušenej. Pod fake sa doručenie zaznamená:

use Carbon\CarbonImmutable;
use Illuminate\Support\Facades\Mail;
use RoundlyConsulting\Campaigns\Campaign;
use RoundlyConsulting\Campaigns\CampaignManager;
use RoundlyConsulting\Campaigns\CampaignRecipient;
use RoundlyConsulting\Campaigns\Facades\Campaigns;
use RoundlyConsulting\Campaigns\Jobs\SendCampaignEmail;

function springSaleJob(): SendCampaignEmail
{
    return new SendCampaignEmail(
        new Campaign(
            uuid: '0b6f4c1e-8d2a-4f0e-9c3b-5a7d2e1f4b6c',
            subject: 'Spring sale',
            content: '<p>The spring sale starts today.</p>',
            fromName: 'Example Shop',
            fromAddress: '[email protected]',
        ),
        new CampaignRecipient(
            uuid: '5d1e2f3a-4b5c-4d6e-8f70-8192a3b4c5d6',
            name: 'Ana Horvat',
            reachableAt: '[email protected]',
            campaignUuid: '0b6f4c1e-8d2a-4f0e-9c3b-5a7d2e1f4b6c',   // it belongs to this campaign
        ),
    );
}

it('records the delivery', function (): void {
    $fake = Campaigns::fake();

    $job = springSaleJob();
    $job->withFakeBatch();
    $job->handle(resolve(CampaignManager::class));   // the fake; with MAIL_MAILER=array in your test env

    $fake->assertRecipientProcessed($job->recipient);
});

it('sends nothing once the campaign is cancelled', function (): void {
    Mail::fake();

    $job = springSaleJob();
    $job->withFakeBatch(cancelledAt: CarbonImmutable::now());
    $job->handle(resolve(CampaignManager::class));

    Mail::assertNothingOutgoing();
});

Skutočný tok

Ak chcete otestovať skutočný tok s dávkou, fake vynechajte a zaregistrujte fake repozitár dávok — balík získava BatchRepository z kontajnera, takže samotný fake busu nestačí. Úložisko v pamäti je v kontajneri registrované ako scoped, takže každý test začína s prázdnym:

use Illuminate\Bus\BatchRepository;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Testing\Fakes\BatchRepositoryFake;
use RoundlyConsulting\Campaigns\Enums\CampaignStatus;
use RoundlyConsulting\Campaigns\Facades\Campaigns;
use RoundlyConsulting\Campaigns\Jobs\SendCampaignEmail;

beforeEach(function (): void {
    // The package resolves BatchRepository from the container, so bind the fake there too.
    $batches = new BatchRepositoryFake;
    app()->singleton(BatchRepository::class, fn () => $batches);
    Bus::fake(batchRepository: $batches);
});

it('queues one email job per recipient', function (): void {
    $campaign = Campaigns::create('Spring sale', '<p>The spring sale starts today.</p>')
        ->from('[email protected]', 'Example Shop')
        ->to(['[email protected]', '[email protected]'])
        ->dispatch();

    $batch = Campaigns::campaign($campaign)->batch();

    expect($campaign->progress->status)->toBe(CampaignStatus::Processing)
        ->and($batch->added)->toHaveCount(2)
        ->and($batch->added[0])->toBeInstanceOf(SendCampaignEmail::class)
        ->and(Campaigns::campaign($campaign)->recipients())->toHaveCount(2);
});

it('leaves a prepared campaign pending', function (): void {
    $campaign = Campaigns::create('Spring sale', '<p>The spring sale starts today.</p>')
        ->from('[email protected]')
        ->to('[email protected]')
        ->prepare();

    expect($campaign->progress->status)->toBe(CampaignStatus::Pending);
});

Nič sa neodošle: joby zostanú vo fake dávke, kde ich môžete overiť. Predvolené nastavenia odosielania sa čítajú cez options-for-laravel, preto v testovacej databáze spustite migráciu options (RefreshDatabase).

Tipy

  • Ak vaše testy ukladajú options s predvolenými nastaveniami, medzi testami volajte Options::flushCache() — options-for-laravel si vyriešené hodnoty pamätá v rámci procesu.
  • Pri databázovom úložisku spustite publikované migrácie kampaní a testovacie dáta pripravte cez factories CampaignRecord a CampaignRecipientRecord.

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 kryptomien

Odoslaní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.