Joe's
Digital Garden

Magic Numbers

The following demonstrates the poor handling of magic numbers as defined in [[Conventions and Smells]]:

class Foo
{
    public function mu(): int
    {
        return 10;
    }

    public function nu(): string
    {
        return "Some text";
    }
}

class TestFoo extends PHPUnitTestCase
{
    public function testMu(): void
    {
        $this->assertEquals(10, (new Foo())->mu());
    }

    public function testNu(): void
    {
        $this->assertEquals("Some text", (new Foo())->nu());
    }
}

As all examples are, this is contrived. Neither the value 10 nor "Some text" tell us anything about the value being returned. It also makes it difficult to test since if the constant were to change in the function, we would also need to change it in the unit test case. By turning these into constants we can reference them outside of the class (e.g. in the test case) as well as provide a name to their values. Now if the constant changes, the unit test does not break, and we now what these values represent:

class Foo
{
    const DECIMAL_BASE = 10;
    const ARBITRARY_STRING = "Some text";

    public function mu(): int
    {
        return self::DECIMAL_BASE;
    }

    public function nu(): string
    {
        return self::ARBITRARY_STRING;
    }
}

class TestFoo extends PHPUnitTestCase
{
    public function testMu(): void
    {
        $this->assertEquals(Foo::DECIMAL_BASE, (new Foo())->mu());
    }

    public function testNu(): void
    {
        $this->assertEquals(Foo::ARBITRARY_STRING, (new Foo())->nu());
    }
}