Информация
- В рейтинге
- 1 399-й
- Откуда
- Рига, Латвия, Латвия
- Дата рождения
- Зарегистрирован
- Активность
Специализация
Фулстек разработчик, Архитектор программного обеспечения
Ведущий
JavaScript
HTML
CSS
Node.js
Vue.js
Веб-разработка
Progressive Web Apps
PostgreSQL
MySQL
GitHub
Я уже отметил выше, что вашу точку зрения понял и принял к сведению :)
Как говорится "В теории, теория и практика неразделимы. На практике это не так" (с) Вы вчера на мой пример рекурсии сказали примерно следующее
Если вы приведете более простой пример этого же алгоритма, то рассмотрим его, если же более простого примера не будет, то попробуйте прикинуть входные данные для того, чтобы протестировать все ветки этого алгоритма из одного тестового метода. В этой функции 4 "цикла" либо вы "мокаете" все зависимости на глубину в 4 цикла, либо вы декомпозируете ваш тест на 4 части и "мокаете" все зависимости, включая вызов самой себя, только на один проход. Вот и прикиньте теперь, где цикломатическая сложность будет выше.
Ничего страшного, так бывает.
Коллега, я нигде не указал, что мой личный опыт — best practice. Не стоит видеть то, чего нет.
Когда-то давным-давно я пытался писАть программы, которые работают при любых условиях. Сейчас мне достаточно, чтобы они отрабатывали при определенных. А что касается любимых приемов, то "на цвет и вкус все фломастеры разные" (с)
Да, я уже понял, что вы с коллегой lair разделяете "зависимости" на "кошерные" и те, на которые "не обращаем внимания". Не беспокойтесь, для меня не составит труда учитывать этот факт при общении с вами. Как вы правильно заметили — всякому овощу свой контекст.
Статья о рекурсии, а не о конвертации ассоциативного массива в объект. Я выложил пример рекурсии, а вы предложили сделать "по-другому". Я поинтересовался, можно ли сделать универсальную фабрику/строитель и получил ответ на свой вопрос. Если вас действительно интересует, как в _typePropsRegistry реализована обработка опциональных и обязательных полей и все остальное — то можете глянуть. Это не мой код, но я брал его за основу, т.к. этот не поддерживает объявление методов через аннотации.
Как бы да. Но на общем фоне обработки HTTP-запроса уже как бы и нет.
Спасибо за пример. Насколько я понял, итоговый код фабрик/строителей для 10-15 объектов выйдет за пределы одного экрана. Более того, с увеличением кол-ва объектов, используемых в API, кол-во фабрик/строителей (как следствие — кол-во кода) также будет расти. В моем случае парсер один и для одного объекта, и для сотни, как и регистратор _typePropsRegistry, который анализирует через рефлексию заданный тип и формирует массив доступных для инициализации свойств.
Можете считать, что объект не зависит от своих составляющих.
Как вам будет угодно считать. Вот пример агрегации из wiki:
если я не ошибаюсь, то агрегация — это зависимость, а _partner1 — это поле.
Да. сложные объекты (complex type) все имеют метод setData($property, $value). Но можно и по-другому, например setProperty($value). Перегоняется JSON, приходящий на API-сервис в объект, содержащий данные (аналог java beans). Был при признателен за пример универсальной фабрики или строителя для создания подобных объектов, код которого бы не выходил за рамки экрана.
Реку́рсия — определение, описание, изображение какого-либо объекта или процесса внутри самого этого объекта или процесса, то есть ситуация, когда объект является частью самого себя.
Это вопрос формулировок. Я считаю что объект зависит от частей, из которых состоит, вы — что нет.
Я не настаиваю на использовании моков при тестировании рекурсии. Более того, я не настаиваю на использовании рекурсии, или использовании моков, или вообще тестирования. Я просто полагаю, что некоторые рекурсивные функции могут быть несколько сложнее, чем вычисление факториала, могут использовать внешние зависимости со сложным поведением и при необходимости (или даже возможности) тестирования таких функций можно использовать мокирование этой же самой функции.
Вы настаиваете на том, что при тестировании рекурсивных функций мокирование категорически неприемлемо?
А можете точнее указать, где именно вы видите дублирование? Было бы хорошо, если бы вы представили свою версию метода, без лишнего дублирования. Это бы сразу придало вес вашим словам. Чтобы было понятнее, поясняю: на вход подается строка с названием типа объекта (класс) и ассоциативный массив данных, на выходе ожидается проинициализированный объект заданного типа. Свойства объекта (properties) могут быть простыми (строка, число), сложными (другой объект с иерархической структурой) или массивом простых или сложных объектов. Метод небольшой, укладывается с один экран, если убрать лишнее дублирование — получится еще меньше. Не думаю, что это займет у вас много времени.
Для простых случаев, типа расчета факториалов, это справедливо, но если рекурсивная функция достаточно сложная, то получаю. Вот, например, преобразование ассоциативного массива в объект заданного типа:
Мне казалось, что "зависимость" более широкое определение, чем "аргумент функции", и не зависит от нашего желания или нежелания проверять что-либо в тесте. Ну да ладно. Да, я тестирую конкретную имплементацию определенного алгоритма, разбивая, при необходимости, ее на составляющие и проверяя каждую составляющую в отдельности. Разве не в этом, в декомпозиции сложной системы на более простые составляющие, заключается основной подход в уменьшении сложности?
Нет, я не мокаю циклы, хотя с удовольствием посмотрел бы на пример. Я мокаю именно зависимости. Рекурсивная функция становится зависимой от самой себя в тот момент, когда обращается сама к себе. Или я и зависимость неправильно понимаю?
Это как-то противоречит тому, что я написал?
Почему вы считаете, что я считаю, что "рекурсивные методы надо тестировать как-то иначе, чем остальные"? Я наоборот считаю, что рекурсивные методы нужно тестировать точно так же, как и остальные. И если нужно использовать при тестах моки — то нужно использовать моки.
Итерации, как правило, сложнее рекурсии в написании и восприятии. А создание сложных входных структур противоречит нами обоими одобренному тезису "Сложная логика в тестах тоже неверно." Но если вы можете сделать тестирование рекурсии простым и без моков — делайте простым и без моков.
Рекурсивный метод вызывает сам себя. Если я тестирую ветку кода, в которой вызывается этот же метод, то, по-хорошему, при втором заходе я должен использовать мок, а не вызывать сам себя. Но я не могу замокировать метод в процессе его выполнения.
С рекурсией так не проходит. Если не создавать обертку. Попробуйте создать два тестовых метода (для обоих условий выхода) для простейшей рекусивной функции:
Абсолютно согласен.
Кстати, можете еще попробовать вытащить данные (email & full name) по всем клиентам, которые совершили транзакции (sales_payment_transaction, нужны данные из поля tnx_id), которые соответствуют определенным методам платежа (sales_order_payment.method) по заказам, созданным в определенный промежуток времени, используя всю мощь Magento ORM.