Testing
Setup
Install Dev Dependencies
composer install
Run Tests
composer test
Run All Quality Checks
composer qa
Bootstrap
The test bootstrap (tests/bootstrap.php) mocks all WordPress functions used by the notification package:
esc_html(),esc_attr(),esc_url(),wp_kses_post()wp_mail(),wp_json_encode(),current_time()get_transient(),set_transient(),delete_transient()add_action(),add_filter(),do_action(),apply_filters()get_current_user_id(),dbDelta()
Testing Notifications
Test a Custom Notification
<?php
declare(strict_types=1);
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
use App\Notifications\OrderShipped;
use WPZylos\Framework\Notification\MailMessage;
class OrderShippedTest extends TestCase
{
public function testViaReturnsExpectedChannels(): void
{
$order = (object) ['id' => 1, 'tracking_url' => 'https://example.com/track'];
$notification = new OrderShipped($order);
$this->assertSame(['mail', 'database'], $notification->via());
}
public function testToMailBuildsCorrectMessage(): void
{
$order = (object) ['id' => 42, 'tracking_url' => 'https://example.com/track/42'];
$notification = new OrderShipped($order);
$notifiable = (object) ['email' => '[email protected]'];
$message = $notification->toMail($notifiable);
$this->assertInstanceOf(MailMessage::class, $message);
$this->assertSame('Order Shipped!', $message->subject);
$this->assertStringContainsString('42', $message->lines[0]);
}
public function testToDatabaseReturnsData(): void
{
$order = (object) ['id' => 42, 'tracking_url' => 'https://example.com'];
$notification = new OrderShipped($order);
$notifiable = (object) [];
$data = $notification->toDatabase($notifiable);
$this->assertArrayHasKey('order_id', $data);
$this->assertSame(42, $data['order_id']);
}
}
Test the NotificationManager
<?php
declare(strict_types=1);
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
use WPZylos\Framework\Notification\Contracts\NotificationChannel;
use WPZylos\Framework\Notification\Notification;
use WPZylos\Framework\Notification\NotificationManager;
class NotificationManagerTest extends TestCase
{
public function testSendDispatchesToChannels(): void
{
$manager = new NotificationManager();
$channel = $this->createMock(NotificationChannel::class);
$channel->expects($this->once())->method('send');
$manager->extend('test', $channel);
$notification = new class extends Notification {
public function via(): array { return ['test']; }
};
$manager->send(new \stdClass(), $notification);
}
}
Test Custom Channels
<?php
declare(strict_types=1);
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
use App\Channels\SlackChannel;
use WPZylos\Framework\Notification\Notification;
class SlackChannelTest extends TestCase
{
public function testSendSkipsWhenNoToSlackMethod(): void
{
$channel = new SlackChannel('https://hooks.slack.com/test');
$notification = new class extends Notification {
public function via(): array { return ['slack']; }
};
// Should not throw — silently skips
$channel->send(new \stdClass(), $notification);
$this->assertTrue(true);
}
}
Test MailMessage Rendering
public function testMailMessageRenders(): void
{
$message = (new MailMessage())
->subject('Test')
->greeting('Hello!')
->line('This is a test.')
->action('Click', 'https://example.com');
$html = $message->render();
$this->assertStringContainsString('<h1>Hello!</h1>', $html);
$this->assertStringContainsString('This is a test.', $html);
$this->assertStringContainsString('https://example.com', $html);
}
Mocking the NotificationManager
In integration tests, you can mock the manager to verify notifications were sent:
$mockManager = $this->createMock(NotificationManager::class);
$mockManager->expects($this->once())
->method('send')
->with(
$this->callback(fn($n) => $n instanceof User),
$this->isInstanceOf(OrderShipped::class)
);
Code Coverage
Generate a coverage report:
XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html coverage/
Open coverage/index.html in your browser to view the report.