Testovanie
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);
});| Asercia | Prejde, 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 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.