Всем привет, есть у меня такой кусок кода, кто может подсказать на его примере, как вообще такое тестировать? Тут все функции ничего не возвращают, а просто что-то выполняют (добавляют в базу данных записи, отправляют запросы в апи, отправляют сообщение в очередь)
final class PartnerApiOfdTicketHandler implements MessageHandlerInterface
{
private OfdTicketMessage $ofdTicketMessage;
private OfdTicketService $ofdTicketService;
private OrangeApiOfdTicketService $orangeApiOfdTicketService;
private OfdTicketStatusProducer $ofdTicketStatusProducer;
private LoggerInterface $logger;
public function __construct(
OfdTicketService $ofdTicketService,
OrangeApiOfdTicketService $orangeApiOfdTicketService,
OfdTicketStatusProducer $ofdTicketStatusProducer,
LoggerInterface $logger
) {
$this->ofdTicketService = $ofdTicketService;
$this->orangeApiOfdTicketService = $orangeApiOfdTicketService;
$this->ofdTicketStatusProducer = $ofdTicketStatusProducer;
$this->logger = $logger;
}
public function __invoke(OfdTicketMessage $ofdTicketMessage): void
{
$this->logger->info(
'OfdTicketMessage was received',
['data' => $ofdTicketMessage->toArray()]
);
$this->ofdTicketMessage = $ofdTicketMessage;
try {
$this->ofdTicketService->create($ofdTicketMessage);
$this->orangeApiOfdTicketService->createTicket($ofdTicketMessage);
$this->ofdTicketService->update(
$ofdTicketMessage,
[
'processed' => true,
'statusCode' => OrangeApiResponseStatus::TICKET_CREATED
]
);
$this->ofdTicketStatusProducer->push(new OfdTicketStatusMessage($ofdTicketMessage->toArray()));
} catch (ConflictException $e) {
$this->handleException($e, 'Need to ack message because: ');
throw new UnrecoverableMessageHandlingException($e->getMessage(), $e->getCode());
} catch (OfdOrangeApiException $e) {
$this->handleException($e, 'Ofd orange api error: ', [
'error' => 'Ofd orange api error: ' . $e->getMessage(),
'statusCode' => $e->getCode()
]);
} catch (TransportExceptionInterface $e) {
$this->handleException($e, 'Can\'t send request to ofd orange api: ', [
'error' => 'Can\'t send request to ofd orange api: ' . $e->getMessage(),
'statusCode' => $e->getCode()
]);
} catch (\Exception|\Throwable $e) {
$this->handleException($e, 'Something went wrong: ', [
'error' => 'Something went wrong: ' . $e->getMessage(),
'statusCode' => InternalExceptionStatus::INTERNAL_ERROR
]);
throw new UnrecoverableMessageHandlingException($e->getMessage(), $e->getCode());
}
}
Это код обработчика сообщений из очереди.
$this->ofdTicketService->create($ofdTicketMessage); - сохранят сообщение в базу данных
$this->orangeApiOfdTicketService->createTicket($ofdTicketMessage); - создает тикет через стороннее api, тело ответа в положительном сценарии всегда пустое, просто приходит код 201, при негативном возникает исключение и тело ответа с ошибкой.
обновляем статус в базе данных
$this->ofdTicketService->update(
$ofdTicketMessage,
[
'processed' => true,
'statusCode' => OrangeApiResponseStatus::TICKET_CREATED
]
);
Отправляем в очередь.
$this->ofdTicketStatusProducer->push(new OfdTicketStatusMessage($ofdTicketMessage->toArray()));
Я в тестировании совсем не шарю. Посмотрел разные видео, почитал документацию, пока не понимаю, как проверять такой код. Я понимаю проверить assert что функция вернулся что-то, но тут функции ничего не возвращают. мокать объекты через $this->createMock тоже смысла нет, так как по сути тогда все методы будут пустыми, а чтобы проверить работоспособность такого кода, по сути нужно
1. Создать тестовую базу данных и накатить миграции.
2. Создать объект сообщения со своими данными, просто через new.
3. Передать его в метод настоящего, не замоканого сервиса $this->ofdTicketService->create($ofdTicketMessage), чтобы тот по настоящему сохранил его в тестовую базу данных.
4. Дальше не знаю, но может есть какие-то методы типа assertExistsInDatabaseTable.
5. $this->orangeApiOfdTicketService->createTicket($ofdTicketMessage) обращение к api вообще не понятно, как тестировать именно в этом случае, и нужно ли вообще? По сути правильной работой его можно считать, если этот метод не выбросит исключение.
6. Проверить обновился ли статус в базе данных.
7. С отправкой в очередь не понятно.
Буду благодарен, если поможете разобраться. Можно тут, можно в конфе, можем договориться в лс.