Size: a a a

2021 July 22

АЕ

Александр Ерин... in symfony
Привет всем, как в симфе правильно работать с моками сервисов?

Задача: создать мок сервиса, прокинуть его в контейнер,
дальше создается handler, который в зависимостях имеет мокнутый сервис

Симфонейский контейнер ругается на то, что нельзя переопределить уже инициализированный сервис(и правильно впринципе делает, так как он уже все скомпилил).

Нагуглить получилось только костыли с рефлексией над контейнером, чего не очень бы хотелось делать.

Кто как работает с моками сервисов в симфе?
источник

AM

Alexey M. in symfony
Я просто видел как обычный подсчет решали циклами и перебором, а потом усложняли доп.запросами в самом цикле и получается, что время на обработку даже 10 записей не хватит )
источник

VM

Volodymyr Melko in symfony
а ты свой класс, который тестишь, не из контейнера доставай
class MyClass {
   public function __construct(SomeService $service, LoggerInterface $logger)
}


а в тесте
$serviceMock = $this->createMock(SomeService::class);
$logger = new NullLogger(); // или тоже мок, или взять из контейнера, если не нужно мокать

$testingUnit = new MyClass($serviceMock, $logger);
источник

АЕ

Александр Ерин... in symfony
Как вариант решения, но в этом случае приходится изменять тест каждыйр аз когда добавляется новая зависимость у хэндлера, и тесты становятся довольно чувствительны к любым изменениям, приходится за этим вручную следить.

Решил проблему так, может кому пригодится:

$handler = $container->get(Handler::class);
$mock = $this->createMock();
$this->bindMock($handler, 'mockPropertyName', $mock);


В целом вроде бы нормально получается даже. Метод bindMock просто через рефлексию подменяет инстанс класса с реального на моковый для конкретного сервиса, ничего изящнее придумать не получилось
источник

ПГ

Павел Г. in symfony
Не раздуплил помогли или нет, но в настройках директорий надо прописать корректно какая директория какой неймспейс представляет.
источник

VM

Volodymyr Melko in symfony
Если ты добавляещь новую зависимость, то ты все равно будешь ее мокать, так что тест поменяется
источник

MV

Moz Vkusni in symfony
Что плохого в изменении тестов, если изменился тестируемый класс?
источник

АЕ

Александр Ерин... in symfony
В том то и прикол, что я буду мокать только тот один сервис, который мне нужно мокнуть, а не все
источник

АЕ

Александр Ерин... in symfony
Моки вообще вещь довольно скользкая, если можно обходиться без них - лучше обходиться без них, они делают тесты хрупкими и заставляют тестировать конкретную реализацию, а не контракты методов
источник

АЕ

Александр Ерин... in symfony
Если метод продолжает выполнять определенный контракт, вне зависимости от его реализации - то тест переписываться не должен
источник

VM

Volodymyr Melko in symfony
Так а если новая зависимость сайд эффекты делает? В сторонние апи ходит, требует наличия данных каких-то в бд?
источник

АЕ

Александр Ерин... in symfony
это уже изменение контракта, если добавляются новые БД или АПИ, а если ты подменил один репозиторий другим - то контракт остается тем же, изменилась имплементация сервиса-зависимости
источник

VM

Volodymyr Melko in symfony
Я видел ещё другой подход, похож на твой, но имхо, чуть изящней.

Например у нас есть хттп клиент, и разные сервисы ходят в разные апихи.

В тест конфиге решали в качестве клиента заглушку-прокси, которая проксирует все запросы во внутренний хттп клиент.
И для этого внутреннего сеттер есть.

Потом в тесте достаешь из контейнера свой сервис и достаешь хттп прокси этот. Сетишь ему в качестве внутреннего клиента мок
источник

VM

Volodymyr Melko in symfony
Ну так одна репа брала с мускуля, а другая с монги. Тебе что так, что эдак надо либо замокать, либо фикстуры грузить другие
источник

AI

Almas Istybaev in symfony
Всем доброго!

Вопрос про api platform, как получить активные (не удаленные) записи у конкретной сущности.

Например, есть юр лицо и у него много документов. Нужно получить  все не  удаленные документы конкретного юрика.  

Фильтрация по itemOperations в доке для 2,5 версий не описано.

Кто как решил подобный вопрос, подскажите куда копать?
источник

VM

Volodymyr Melko in symfony
$user->getDocuments()->filter(fn(Document $d) => !$d->isRemoved())->toArray()
источник

AI

Almas Istybaev in symfony
а где это прописывать?) Без api platform если, то есть репозитории сушьности. Но в доке api platform не нашел как использовать репозитории.
источник

VM

Volodymyr Melko in symfony
можно эту магию спрятать внутри самого юзера и там будет метод getActiveDocuments или getDocuments(bool $removedAlso = true) к примеру
источник

VM

Volodymyr Melko in symfony
в самой сущности оО
источник

VM

Volodymyr Melko in symfony
так же как любой другой сервис, инжекти и используй
источник