Solution: 4
PHPUnit 10.2.2 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.14 Configuration: phpunit.xml ...... 6 / 6 (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 can be converted to centimeters ✔ Meters cannot be negative OK (6 tests, 6 assertions)
Output of phpunit --testdox
Execute phpunit --testdox
The conversion in the other direction works the same way:
#[Test]
public function meters_can_be_converted_to_centimeters(): void
{
$measure = new Meter(1.53);
$this->assertEquals(new Centimeter(153), $measure->asCentimeter());
}
MeasurementsTest.php
Once we are satisfied that the test fails, we add the appropriate method to the Meter
class:
public function asCentimeter(): Centimeter
{
return new Centimeter((int) ($this->meters * 100));
}
Meter.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_can_be_converted_to_centimeters(): void
{
$measure = new Meter(1.53);
$this->assertEquals(new Centimeter(153), $measure->asCentimeter());
}
#[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;
}
public function asCentimeter(): Centimeter
{
return new Centimeter((int) ($this->meters * 100));
}
private function ensureNotNegative(float $meters): void
{
if ($meters < 0) {
throw new RuntimeException('Measure cannot be negative');
}
}
}
Meter.php