Skip to content

Commit 038f624

Browse files
committed
add humble pattern example
1 parent 222e91f commit 038f624

File tree

1 file changed

+112
-1
lines changed

1 file changed

+112
-1
lines changed

README.md

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1409,7 +1409,118 @@ final class SubscriptionSuspendingTest extends TestCase
14091409

14101410
## Humble pattern
14111411

1412-
[TODO]
1412+
How to properly unit test a class like this?
1413+
1414+
```php
1415+
class ApplicationService
1416+
{
1417+
public function __construct(
1418+
private OrderRepository $orderRepository,
1419+
private FormRepository $formRepository
1420+
) {}
1421+
1422+
public function changeFormStatus(int $orderId): void
1423+
{
1424+
$order = $this->orderRepository->getById($orderId);
1425+
$soapResponse = $this->getSoapClient()->getStatusByOrderId($orderId);
1426+
$form = $this->formRepository->getByOrderId($orderId);
1427+
$form->setStatus($soapResponse['status']);
1428+
$form->setModifiedAt(new \DateTimeImmutable());
1429+
1430+
if ($soapResponse['status'] === 'accepted') {
1431+
$order->setStatus('paid');
1432+
}
1433+
1434+
$this->formRepository->save($form);
1435+
$this->orderRepository->save($order);
1436+
}
1437+
1438+
private function getSoapClient(): \SoapClient
1439+
{
1440+
return new \SoapClient('https://legacy_system.pl/Soap/WebService', []);
1441+
}
1442+
}
1443+
```
1444+
1445+
:heavy_check_mark: It's required to split up overcomplicated code to separate classes.
1446+
1447+
```php
1448+
final class ApplicationService
1449+
{
1450+
public function __construct(
1451+
private OrderRepositoryInterface $orderRepository,
1452+
private FormRepositoryInterface $formRepository,
1453+
private FormApiInterface $formApi,
1454+
private ChangeFormStatusService $changeFormStatusService
1455+
) {}
1456+
1457+
public function changeFormStatus(int $orderId): void
1458+
{
1459+
$order = $this->orderRepository->getById($orderId);
1460+
$form = $this->formRepository->getByOrderId($orderId);
1461+
$status = $this->formApi->getStatusByOrderId($orderId);
1462+
1463+
$this->changeFormStatusService->changeStatus($order, $form, $status);
1464+
1465+
$this->formRepository->save($form);
1466+
$this->orderRepository->save($order);
1467+
}
1468+
}
1469+
```
1470+
1471+
```php
1472+
final class ChangeFormStatusService
1473+
{
1474+
public function changeStatus(Order $order, Form $form, string $formStatus): void
1475+
{
1476+
$status = FormStatus::createFromString($formStatus);
1477+
$form->changeStatus($status);
1478+
1479+
if ($form->isAccepted()) {
1480+
$order->changeStatus(OrderStatus::paid());
1481+
}
1482+
}
1483+
}
1484+
```
1485+
1486+
```php
1487+
final class ChangingFormStatusTest extends TestCase
1488+
{
1489+
/**
1490+
* @test
1491+
*/
1492+
public function changing_a_form_status_to_accepted_changes_an_order_status_to_paid(): void
1493+
{
1494+
$order = new Order();
1495+
$form = new Form();
1496+
$status = 'accepted';
1497+
$sut = new ChangeFormStatusService();
1498+
1499+
$sut->changeStatus($order, $form, $status);
1500+
1501+
self::assertTrue($form->isAccepted());
1502+
self::assertTrue($order->isPaid());
1503+
}
1504+
1505+
/**
1506+
* @test
1507+
*/
1508+
public function changing_a_form_status_to_refused_not_changes_an_order_status(): void
1509+
{
1510+
$order = new Order();
1511+
$form = new Form();
1512+
$status = 'new';
1513+
$sut = new ChangeFormStatusService();
1514+
1515+
$sut->changeStatus($order, $form, $status);
1516+
1517+
self::assertFalse($form->isAccepted());
1518+
self::assertFalse($order->isPaid());
1519+
}
1520+
}
1521+
```
1522+
1523+
However, ApplicationService probably should be tested by an integration test with only mocked FormApiInterface.
14131524

14141525
## Trivial test
14151526

0 commit comments

Comments
 (0)