📡 You're offline — showing cached content
New version available!
Quick Access
Python Intermediate

PHP Unit Testing with PHPUnit: Complete Guide

Master PHPUnit — test classes, assertions, setUp/tearDown, mocking dependencies, data providers, and test coverage reporting.

EzyCoders Admin November 28, 2025 11 min read 0 views
PHP Unit Testing PHPUnit Complete Guide
Share: Twitter LinkedIn WhatsApp

PHP Unit Testing with PHPUnit

Tests are the safety net that lets you refactor with confidence. PHPUnit is the standard testing framework for PHP. Well-tested code has fewer bugs, is easier to refactor, and signals professionalism in interviews and code reviews.

Installation and First Test

composer require --dev phpunit/phpunit
./vendor/bin/phpunit --version
<?php
// src/Calculator.php
class Calculator {
    public function add(float $a, float $b): float { return $a + $b; }
    public function divide(float $a, float $b): float {
        if ($b === 0.0) throw new DivisionByZeroError("Cannot divide by zero");
        return $a / $b;
    }
}

// tests/CalculatorTest.php
use PHPUnit\Framework\TestCase;

class CalculatorTest extends TestCase {
    private Calculator $calc;

    protected function setUp(): void {
        $this->calc = new Calculator();
    }

    public function test_add_two_positive_numbers(): void {
        $result = $this->calc->add(2, 3);
        $this->assertEquals(5, $result);
    }

    public function test_add_negative_numbers(): void {
        $this->assertEquals(-1, $this->calc->add(-2, 1));
    }

    public function test_divide_throws_on_zero(): void {
        $this->expectException(DivisionByZeroError::class);
        $this->calc->divide(10, 0);
    }
}

Assertions Reference

<?php
$this->assertEquals(expected, actual);       // == equality
$this->assertSame(expected, actual);         // === equality (strict)
$this->assertTrue(condition);
$this->assertFalse(condition);
$this->assertNull($value);
$this->assertNotNull($value);
$this->assertCount(3, $array);
$this->assertArrayHasKey('name', $array);
$this->assertStringContainsString('php', $str);
$this->assertInstanceOf(User::class, $obj);

Mocking Dependencies

<?php
class UserService {
    public function __construct(private UserRepository $repo) {}
    public function getActiveUser(int $id): ?array {
        $user = $this->repo->findById($id);
        return ($user && $user['active']) ? $user : null;
    }
}

class UserServiceTest extends TestCase {
    public function test_returns_null_for_inactive_user(): void {
        // Mock the repository — don't hit real DB
        $repo = $this->createMock(UserRepository::class);
        $repo->method('findById')
             ->with(42)
             ->willReturn(['id' => 42, 'name' => 'Rahul', 'active' => false]);

        $service = new UserService($repo);
        $this->assertNull($service->getActiveUser(42));
    }
}

Q: What is the difference between a unit test and an integration test?

A unit test tests a single class or function in isolation — all dependencies are mocked. Fast, reliable, no database. An integration test tests multiple components working together — real database, real file system. Slower but tests actual wiring. Both are needed: unit tests for logic, integration tests for components working together.

EzyCoders Admin
Written by
EzyCoders Admin

Team Lead and Full-Stack Developer with experience in PHP, JavaScript, SQL, DSA, and System Design. Passionate about software engineering, scalable web technologies, and helping developers prepare for coding interviews and tech careers through practical tutorials and professional guidance.

Comments (0)

No comments yet. Be the first!

Leave a Comment