Solution: 3
PHPUnit 10.2.2 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.14 Configuration: phpunit.xml ..... 5 / 5 (100%) Time: 00:00.002, Memory: 24.41 MB Measurements ✔ Centimeters can be converted to int ✔ Centimeters can be converted to meters ✔ Centimeters cannot be negative ✔ Meters can be converted to float ✔ Meters cannot be negative OK (5 tests, 5 assertions)
Output of phpunit --testdox
Execute phpunit --testdox
The conversion to meter is actually nothing else than the conversion to an integer, but of course with meter
as return type. So we can write a corresponding test:
#[Test]
public function centimeters_can_be_converted_to_meters(): void
{
$centimeters = 123;
$measure = new Centimeter($centimeters);
$this->assertEquals(new Meter(1.23), $measure->asMeter());
}
MeasurementsTest.php
This is quickly implemented:
public function asMeter(): Meter
{
return new Meter($this->centimeters / 100);
}
Centimeter.php
The solution at a glance:
<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
#[CoversClass(Meter::class)]
#[CoversClass(Centimeter::class)]
class MeasurementsTest extends TestCase
{
#[Test]
public function centimeters_can_be_converted_to_int(): void
{
$centimeters = 23;
$measure = new Centimeter($centimeters);
$this->assertEquals($centimeters, $measure->asInt());
}
#[Test]
public function centimeters_can_be_converted_to_meters(): void
{
$centimeters = 123;
$measure = new Centimeter($centimeters);
$this->assertEquals(new Meter(1.23), $measure->asMeter());
}
#[Test]
public function centimeters_cannot_be_negative(): void
{
$this->expectException(RuntimeException::class);
new Centimeter(-1);
}
#[Test]
public function meters_can_be_converted_to_float(): void
{
$meters = 1.5;
$measure = new Meter($meters);
$this->assertEquals($meters, $measure->asFloat());
}
#[Test]
public function meters_cannot_be_negative(): void
{
$this->expectException(RuntimeException::class);
new Meter(-1);
}
}
MeasurementsTest.php
<?php declare(strict_types=1);
class Centimeter
{
private readonly int $centimeters;
public function __construct(int $centimeters)
{
$this->ensureNotNegative($centimeters);
$this->centimeters = $centimeters;
}
public function asInt(): int
{
return $this->centimeters;
}
public function asMeter(): Meter
{
return new Meter($this->centimeters / 100);
}
private function ensureNotNegative(int $centimeters): void
{
if ($centimeters < 0) {
throw new RuntimeException('Measure cannot be negative');
}
}
}
Centimeter.php
<?php declare(strict_types=1);
class Meter
{
private readonly float $meters;
public function __construct(float $meters)
{
$this->ensureNotNegative($meters);
$this->meters = $meters;
}
public function asFloat(): float
{
return $this->meters;
}
private function ensureNotNegative(float $meters): void
{
if ($meters < 0) {
throw new RuntimeException('Measure cannot be negative');
}
}
}
Meter.php