Skip to main content

Documentation Index

Fetch the complete documentation index at: https://kawax.biz/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Most features are available via the Bluesky Facade, so you can use standard Laravel mocks when writing tests. For general Laravel package testing, see package-testing.

Facade mocks

Use Bluesky::expects() to mock entire method chains.
use Revolution\Bluesky\Facades\Bluesky;
use Illuminate\Support\Facades\Http;
use Illuminate\Http\Client\Response;

Bluesky::expects('login->getProfile->json')->once()->andReturn([]);
Bluesky::expects('login->getProfile')->once()->andReturn(new Response(Http::response([])->wait()));

HTTP fake

laravel-bluesky uses Laravel’s HTTP client internally. Add Http::preventStrayRequests() to your test setUp() to catch unexpected external requests immediately.
use Revolution\Bluesky\Facades\Bluesky;
use Illuminate\Support\Facades\Http;

protected function setUp(): void
{
    parent::setUp();

    Http::preventStrayRequests();
}

public function test_post(): void
{
    Http::fake();

    Http::fakeSequence()
        ->push();

    Bluesky::expects('resolveHandle->json')->once()->andReturn('did');
}
Http::preventStrayRequests() throws an exception if a real HTTP request is made during the test. This makes it easy to detect unintended external calls and keeps your test suite fast and reliable.

Features that cannot be mocked

FeedGenerator

FeedGenerator is called by the Bluesky server, so there is no end-to-end mock. However, the algorithm part of FeedGenerator can be mocked.
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\FeedGenerator\FeedGenerator;

public function test_feed_generator(): void
{
    FeedGenerator::register(name: 'test', algo: function (?int $limit, ?string $cursor) {
        // Authentication is required due to a temporary API restriction
        $posts = Bluesky::login(identifier: config('bluesky.identifier'), password: config('bluesky.password'))
            ->searchPosts(q: '#bluesky')->collect('posts');
        $feed = $posts->map(function (array $post) {
            return ['post' => data_get($post, 'uri')];
        })->toArray();
        return ['feed' => $feed];
    });

    Bluesky::expects('login->searchPosts->collect')->once()->andReturn(collect([['uri' => 'at://']]));

    $response = $this->get(route('bluesky.feed.skeleton', ['feed' => 'at://did:/app.bsky.feed.generator/test']));

    $response->assertSuccessful();
    $response->assertJson(['feed' => [['post' => 'at://']]]);
}

Core

The “Core” functionality of Bluesky/AtProtocol does not involve external access, so mocking is not needed.
Last modified on April 25, 2026