Courses/PHP/PHPUnit Testing

    Lesson 45 • Advanced

    PHPUnit Testing 🧪

    Write unit tests, use test doubles (mocks, stubs, fakes), and test-drive your PHP code with PHPUnit for rock-solid applications.

    What You'll Learn in This Lesson

    • • Write unit tests with assertions and expected exceptions
    • • Use stubs, mocks, fakes, and spies for dependencies
    • • Test a real registration service with isolated components
    • • Understand the test pyramid: unit vs integration vs E2E
    • • Run tests and interpret results

    Unit Testing Fundamentals

    A unit test verifies a single function or class in isolation. Each test follows the Arrange-Act-Assert pattern: set up inputs, call the function, verify the output. Good tests are fast, independent, and deterministic — they always produce the same result.

    Try It: Unit Test Suite

    Test a Calculator and ShoppingCart with assertions and exception handling

    Try it Yourself »
    JavaScript
    // Unit Testing with PHPUnit
    console.log("=== Why Write Tests? ===");
    console.log();
    console.log("  Without tests: 'I think it works' (until production breaks)");
    console.log("  With tests:    'I know it works' (tests prove it)");
    console.log();
    console.log("  Test types:");
    console.log("  • Unit tests     — Test a single function/class in isolation");
    console.log("  • Integration    — Test multiple components together");
    console.log("  • Feature/E2E   — Test full HTTP request/response cycle");
    
    ...

    Mocks, Stubs & Fakes

    Real dependencies (databases, email services, APIs) make tests slow and unreliable. Replace them with test doubles: stubs return pre-set values, fakes provide working in-memory implementations, and mocks verify that methods were called with the correct arguments.

    Try It: Test Doubles

    Test user registration with fake repositories and stub email services

    Try it Yourself »
    JavaScript
    // Test Doubles: Mocks, Stubs, and Fakes
    console.log("=== Test Doubles Explained ===");
    console.log();
    console.log("  Stub:  Returns pre-configured answers. Doesn't verify calls.");
    console.log("  Mock:  Verifies that specific methods were called correctly.");
    console.log("  Fake:  Working implementation (e.g., in-memory database).");
    console.log("  Spy:   Records calls for later inspection.");
    console.log();
    
    // Demonstrate test doubles
    class EmailServiceStub {
      constructor() { this.sent = [];
    ...

    ⚠️ Common Mistakes

    ⚠️
    Testing implementation, not behavior — Don't test that a specific private method was called. Test that the public output is correct. Refactoring shouldn't break tests.
    ⚠️
    Tests that depend on each other — Each test must create its own state. Never rely on another test running first or leaving data behind.
    💡
    Pro Tip: Aim for the test pyramid: many unit tests (fast), some integration tests (medium), few E2E tests (slow). Run unit tests on every commit, integration tests in CI.

    📋 Quick Reference — PHPUnit

    ConceptDescription
    assertEquals()Assert two values are equal
    expectException()Assert a specific exception is thrown
    createMock()Create a mock object for a class
    setUp()Runs before each test method
    @dataProviderRun same test with different inputs

    🎉 Lesson Complete!

    You can now write professional tests! Next, learn to build and publish reusable Composer packages.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service