Arrange, Act, Assert (AAA) паттерн

При написании по данному паттерну код любого Unit теста состоит из 3 частей:

При такой структуре - улучшается читабельность и восприятие теста.

Использование анонимных классов для написания более простых тестов

Наши классы согластно D из SOLID должны зависеть от интерфейсов. Если нужно протестировать процедуру тестируемого класса, которая вызывает процедуру из вложенного в него интерфейса - то достаточно удобно не мокать все зависимости вложенного интерфейса, а создать анонимный класс, его реализующий:

final class SomeService
{
   /**
    * @var SenderInterface
    */
    private $sender;

    public __constructor(SenderInterface $sender)
    {
        $this->sender = $sender;
    }

    public function publish(): void
    {
        // ... same code

        $this->sender->send();
    }
}

final class testSomeService extends TestCase
{
    /**
     * @test
     */
    public publish()
    {
        $sender = $this-createSender();
        $someService = new SomeService($sender);

        $someService->publish();
        
        $this->assertTrue($sender->isSended());

    }

    private function createSender(): SenderInterface
    {
        return new class() implements SenderInterface
        {
            private $isSend = false;
            public function send():void
            {
                $this->isSend = true;
            }

            public function isSended(): bool
            {
                return $this->isSend;
            }
        }
    }
}

Но если зависимостей не много - createMock и стандартный флоу UnitTest - лучший выбор… Под капотом будет происходить примерно то же самое.

Источники

Using anonymous classes to write simpler tests https://matthiasnoback.nl/2014/07/a-better-testing-experience/