Witam,
chciałbym w tym temacie zadawać pytania odnośnie testów w istniejącym projekcie, w którym działam od dłuższego czasu.
Background: Na pokładzie mamy CakePHP 4 (czyli Active Record), PHP 7.4. Pierwotni twórcy wzięli sobie do serca zasady "Fat controllers" i "Fat models" (choć to drugie znacznie mniej), brak testów, kilka dużych serwisów, często głupie mylące nazwy, brak separacji kodu itd..., testów brak. Generalnie projekt jest napisany bardzo po "cake'owemu", staram się poprawiać różne kwiatki na tyle ile mam wiedzy, nowe funkcjonalności (jak np integracje) staram się pakować do osobnych namespaców poza frameworkiem, zamiast używać powiązanych z frameworkiem modeli/komponentów.
Chciałbym wprowadzić do projektu testy, ale jestem w temacie początkujący i mam wiele pytań więc mam nadzieję, że pomożecie mi nieco w nauce i rozwiewaniu wątpliwości.
ps. proszę sobie darować rady typu "CakePHP? Kto w tym jeszcze pisze... tylko symfony" :)
Do sedna... Pierwszy temat na rozgrzewkę. Mam model FactoryOrder, gdzie zapisuję poszczególne części zamówienia dla różnych fabryk. Poniżej kod:
public function createForOrder(array $orderItems = []): void
{
$groupedByFactory = $this->groupByFactory($orderItems);
foreach ($groupedByFactory as $factoryGroup) {
$factoryEntity = $this->newEmptyEntity();
$factoryEntity = $this->patchEntity($factoryEntity, $factoryGroup);
$this->save($factoryEntity);
}
}
private function groupByFactory(array $orderItems = []): array
{
$groups = [];
$deliveryPart = 1;
foreach ($orderItems as $item) {
if (!isset($groups[$item->factory_id])) {
$groups[$item->cp_provider_id] = [
'order_id' => $item->order_id,
'factory_id' => $item->factory_id,
'factory' => $item->factory_name,
'delivery_part' => $deliveryPart,
];
$deliveryPart++;
}
}
return $groups;
}
Chciałbym przetestować metodę groupByFactory, która powinna zwrócić mi odpowiednią strukturę przed zapisem, jednak jest to metoda prywatna. I teraz kilka pytań:
- czy powinienem po prostu użyć ReflectionMethod::setAccessible w PHPUnit?
- może powinienem zmienić private na public (to raczej zły pomysł, bo niby dlaczego taka metoda miałaby być częścią API klasy)
- a może powinienem wydzielić tę metodę do serwisu, który powinien się zająć obróbką tych danych (wtedy metoda będzie public, więc nie ma problemu) -> to wydaje mi się najbardziej sensowne
Które rozwiązanie będzie najlepsze?