tyloo/atc

Fluent API testing for Symfony with JSON Schema validation, container mocking, and in-memory infrastructure swaps.

Maintainers

Package info

github.com/tyloo/atc

Type:symfony-bundle

pkg:composer/tyloo/atc

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-05-08 14:35 UTC

This package is auto-updated.

Last update: 2026-05-08 14:57:43 UTC


README

atc — APITestCase

atc — APITestCase

Fluent API testing for Symfony with JSON Schema validation, container mocking, and in-memory infrastructure swaps.

Latest version Downloads CI Coverage License PHP version Symfony 7 | 8

Why atc?

Symfony's WebTestCase gives you the kernel and a browser. Everything else — fluent assertions, JSON Schema validation, container mocking, in-memory transports — you build yourself, every project. atc is the layer that closes that gap, inspired by Laravel's testing helpers and api-platform/core's ApiTestCase but purpose-built for modern Symfony.

Highlights

  • Fluent HTTP DSL$this->get('/users')->assertOk()->assertJsonContains([...])
  • JSON Schema (Draft 2020-12), JSON subset, and JSONPath assertions
  • Pluggable auth via the AuthenticatorInterface plus actingAs($user) and withToken()
  • Container-aware mockingmockService, partialMockService, setService, defaultMocks()
  • In-memory swaps by default for Messenger, Mailer, Notifier, HTTP client, Cache, and Clock
  • Database, performance, and infrastructure assertionsassertDatabaseHas, assertResponseTimeLessThan, assertEmailSent, assertMessageDispatched, …

Installation

composer require --dev tyloo/atc

Quick start

One test method. Auth, mocking, fluent assertions, JSON Schema validation, database checks — all without setup boilerplate.

public function test_creates_a_user_and_sends_welcome_email(): void
{
    $admin = AdminFactory::createOne(); // create an admin via a Zenstruck Foundry factory

    $this->mockService(MailerInterface::class) // swap the real Mailer for a PHPUnit mock in the container
        ->expects(self::once())                // expect exactly one outbound call
        ->method('send');                      // …specifically MailerInterface::send()

    $this->actingAs($admin)                                   // authenticate every following request as $admin
        ->post('/api/users', json: [                          // POST with a JSON body (Content-Type set automatically)
            'email' => 'alice@example.com',
            'name'  => 'Alice',
        ])
        ->assertCreated()                                     // HTTP 201 Created
        ->assertMatchesJsonSchema('users/create.json')        // validate the body against a JSON Schema (Draft 2020-12)
        ->assertJsonPath('$.data.email', 'alice@example.com') // pinpoint a single field via JSONPath
        ->assertHeader('Location', '/api/users/1');           // verify the Location header points at the new resource

    $this->assertDatabaseHas(User::class, ['email' => 'alice@example.com']); // confirm Doctrine actually persisted the row
}

One method. Seven infrastructure concerns covered without a single line of setup boilerplate.

Trait reference

Trait Purpose
InteractsWithApi HTTP requests + fluent response assertions (in base class)
InteractsWithContainer Container service mocking (in base class)
InteractsWithAuth actingAs, authenticators (in base class)
InteractsWithDatabase assertDatabaseHas, etc.
InteractsWithMessenger In-memory transport + assertMessageDispatched
InteractsWithMailer Email assertions
InteractsWithNotifier Notification assertions
InteractsWithHttpClient MockHttpClient + assertions
InteractsWithCache ArrayAdapter + assertions
InteractsWithClock MockClock with travel/freeze

Documentation

See docs/:

Recommended companions

Contributing

See CONTRIBUTING.md and our Code of Conduct.

Security

Report vulnerabilities via GitHub Security Advisories. See SECURITY.md.

License

MIT © Julien Bonvarlet