Информация об изменениях

Сообщение Re[8]: Что такое Dependency Rejection от 17.11.2023 11:19

Изменено 17.11.2023 11:35 ·

Re[8]: Что такое Dependency Rejection
Здравствуйте, Pauel, Вы писали:

P>>>Тесты "как написано", технически не дают никаких гарантий — вызвал другой метод репозитория, результат тот же, а тесты сломались. Вот вам и "то же самое"

P>·>Это уже детали реализации — что именно тестируют тесты. Если я хочу тестировать факт вызова определённого метода, то тест и должен сломаться. Что именно покрывает тест — это должен решать программист. Моки к этому отношения не имеют вообще никакого.
P>Забавный плюрализм в одной голове — в одном треде вы клеймите позором "тесты как написано", тк "они ничего не тестируют", а здесь это уже "детали реализации"
Это потому что ты сам с собой споришь и с темы спрыгиваешь.

P>Как вас понимать, какая версия вашего мнения считается более актуальной?

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

P>>>Например, научить новичка внятно пользоваться моками да правильно покрывать тесты используя такой подход довольно трудно, на это уходят годы. А потому рано или поздно будете ловить последствия в проде.

P>·>Это всё риторика. Любые тесты искажают действительность, просто по определению. Моки — тут вообще не при чём.
P>Любые и все по разному, в разной степени. Моки по своей сути сильнее всего этому подвержены. Пол-приложения не работает при зеленых тестах — обычное дело с моками.
Ещё раз повторюсь. Моки — инструмент. Если ты молотком пользоваться не умеешь и постоянно попадаешь по пальцам, то правильным решением будет научиться пользоваться молотком, а не продолжать закручивать гвозди отвёрткой.

P>·>Моки это всего лишь механизм передачи данных от одного участка кода другому. Пюрешки могут использовать только передачу параметров и возвращаемое значение. Моки — дополнительно позволяют передавать инфу через вызовы методов. Вот и вся разница.

P>Не вся — моки могут добавлять то чего в природе нет, не водится, или выворачивать наизнанку. Соответствие моков реальному поведению системы всегда остаётся на совести разработчика, а следовательно человеческий фактор в его максимальном проявлении.
В параметры тоже можно передавать то чего в природе нет. И что?

P>>>Обмазываетесь моками — значит время на разработку тестов больше, тк тесты хрупкие.

P>·>Моки лишь дополнительный инструмент. Можно им всё сломать, а можно сделать красиво.
P>У вас моки стали какой то панацеей. Вас послушать так у моков одни преимущества, без каких либо недостатков.
Это твои фантазии.

P>>>Моки это инструмент решения проблем, а не способ выражения намерений. А раз так, то нужно сперва решить проблему, тогда и отпадет необходимость применять этот инструмент.

P>·>Решения каких проблем?
P>Зависимости. Моки отрезают зависимости во время тестирования. Что характерно, моки далеко это не единственный инструмент решения этой поблемы, и далеко не самый эффективный.
Ты так и не показал как ты предлагаешь решать эту проблему, только заявил, что решается одной строчкой, но не показал как. Проигнорировал вопрос дважды: Напиши однострочный интеграционный тест для tryAcceptComposition.

P>А у вас он стал панацеей

Не панацеей, а конкретным решением твоей конкретной проблемы.

P>>>Эти вещи связаны исключительно конкретным пайплайном. А вот логически это разные вещи. Тестировать сам пайплайн удобнее интеграционными тестам — прогнал один, значит пайпалайн работает. А вот отдельные части пайплайна — дешовыми юнит-тестами, их можно настрочить тыщи, хоть генерируй по спеке, время на запуск все равно 0 секунд.

P>·>Я о чём и говорю. Шило на мыло меняешь, правда ценой удвоения количества кода.
P>Если есть выбор, моком или простым юнит-тестом, то юнит-тест всегда эффективнее.
Классика же — у каждой проблемы есть простое, ясное, эффективное, но неправильное решение.

P>Удвоение количества — это как раз про моки. При одинаковом покрытии кейсов мокам нужно больше кода.

Я говорю конкретно о статье. Там кол-во кода удвоилось. Тестовое покрытие упало в несколько раз, зато Без Моков™.

P>·>Варианта чего? Вынести пюрешку можно банальным extract method refactoring и покрыть отдельно — если это имеет хоть какую-то практическую пользу. Мой поинт в том, что в статье практической пользы делать закат вручную мне не удалось увидеть.

P>Так вы хотели, что бы вам в трех словах все тайны мироздания раскрыли? Все статьи такие, что там можно найти частный случай и заткнуть всё сразу.
Я хотел, чтобы мне разъяснили нераскрытый вопрос в статье.

P>·>Я предлагаю использовать ооп. На минутку — что требует бизнес? Реализацию сущности MaitreD.

P>Нет, не требует. Бизнесу до ваших сущностей никакого дела нет. А потому разработчик имеет право выбирать, нужна ли ему такая сущность, и как он её будет моделировать — объектами, классами, актерами итд итд итд Хоть набором переменных, абы это имело практическое обоснование
Ясен пень, можно хоть на brainfuck писать, без этого вашего ООП. Но чем модель ближе — тем лучше. ООП как раз направлено на моделирование бизнес-требований как можно более похожим образом — именованная сущность там — именованная сущность здесь. Набор переменных это круто, конечно, он обычно только как практическое обоснование для жоп-секьюрити.

P>·>В статье на замену предложено вычленить локальное нутро реализации метода, вынести наружу, чтобы получилось вот это: int -> (DateTimeOffset -> Reservation list) -> (Reservation -> int) -> Reservation — это вообще чо??!.

P>Это описание конкретного пайплайна. В ооп подходе у вас будет примерно такая же штукенция. Покрасивее будет, т.к. именованая. Но принципиально всё сохранится. В том и то и бенефит.
Какова цель этой штуки? Зачем нам описывать конкретный пайплайн? Что можно полезного делать с этим описанием? Как проверить, что писание верное? Откуда взялось, что "принципиально всё сохранится"?

P>Проблема с самой статье

P>1. в ооп стоит делать так, как автор показывает для фп варианта — больше контроля, меньше моков, больше юнит-тестов
И кода стало больше, и бОльшая часть нетривиального кода не протестирована.

P>2. если в фп задаться целью сделать как автор для ооп вариана — можно просто убиться

А какой целью надо задаваться-то?

P>Это правило для работы с глубокоми иерахиями чего угодно — глубокую запутанную превращаем в плоскую одноуровневую. методы становятся длиннее, но зависимостями управлять легче тк иерархия неглубокая.

Ну так внедрение зависимостей DI+CI это и есть плоская иерархия. В конструкторе все зависимости, методы — целевая бизнес-логика. В статье это и было показано, что такой подход эквивалентен частичному применению функций — код под капотом идентичный получается.

P>>> Вы по прежнему думаете, что моки избавляют от интеграционных тестов. Ровно наоборот — сверх обычных юнитов вам надо понаписывать моки на все кейсы, и всё равно придется писать интеграционные тесты.

P>·>Зачем писать моки на все кейсы? Моки делаются не для кейсов, а для зависимостей. Тут одна зависимость — репозиторий — значит один мок. Неважно сколько кейсов.
P>Ваш мок должен поддерживать все эти кейсы, что очевидно. Думаете мок сам догадается, какие кейсы ему поддерживать?
Ещё раз повторюсь — мок это лишь способ передачи данных внуть метода. В твоём случае ровно то же придётся делать, но передавать через параметры, а не через мок, вот и вся разница.

P>·>Юнит-тестов нужно только два — успешная и неуспешная резервация. Интеграционный тест только один — что MaitreD успешно интегрируется со всеми своими зависимостями.

P>Юнит-тестов нужно гораздо больше — в зависимости от того, сколько у нас параметров, состояний итд.
Сосредоточься на обсуждаемой теме. Я говорю конкретно о коде в статье. Там видно сколько конкретно параметров, состояний и т.д.

P>>>На основе коротких функций мы можем менять компоновку уже по ходу пьесы подстраиваясь под изменения треботваний, а не бетонировать код на все времена.

P>·>"зарезервировать столик" — это Responsibility выполняемое Actor-ом MaitreD. Это понятно бизнесу.
P>Бизнесу до этого никакого дела нет. MaitreD это абстракция уровня реализации.
Слова Responsibility и Actor — это из словаря FRD. Т.е. именно эта терминология используется бизнесом для общения с девами.

P>·>Ты не отвлекайся. Код в статье рассматривай. Расскажи куда там воткнуть это всё в tryAcceptComposition или куда там получится. Я хочу рассмотреть пример когда у метода будет больше одной зависимости. А ты мне предлагаешь зависимости внедрять неявно через аннотации и глобальные переменные.

P>Это ваши фантазии. Я ничего не предлагаю внедрать неявно, тем более с глобальными переменными. Это вы с голосами в голове спорите.
Аннотации именно так и работают.

P>·>Ужас. annotation-driven development. Прям Spring, AOP, ejb, 00-е, application container, framework, middleware. Закопай обратно.

P>Это то куда идут по большому счету все платформы.
Когда отдают на аутсорс в индию, да.
Re[8]: Что такое Dependency Rejection
Здравствуйте, Pauel, Вы писали:

P>>>Тесты "как написано", технически не дают никаких гарантий — вызвал другой метод репозитория, результат тот же, а тесты сломались. Вот вам и "то же самое"

P>·>Это уже детали реализации — что именно тестируют тесты. Если я хочу тестировать факт вызова определённого метода, то тест и должен сломаться. Что именно покрывает тест — это должен решать программист. Моки к этому отношения не имеют вообще никакого.
P>Забавный плюрализм в одной голове — в одном треде вы клеймите позором "тесты как написано", тк "они ничего не тестируют", а здесь это уже "детали реализации"
Это потому что ты сам с собой споришь и с темы спрыгиваешь.

P>Как вас понимать, какая версия вашего мнения считается более актуальной?

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

P>>>Например, научить новичка внятно пользоваться моками да правильно покрывать тесты используя такой подход довольно трудно, на это уходят годы. А потому рано или поздно будете ловить последствия в проде.

P>·>Это всё риторика. Любые тесты искажают действительность, просто по определению. Моки — тут вообще не при чём.
P>Любые и все по разному, в разной степени. Моки по своей сути сильнее всего этому подвержены. Пол-приложения не работает при зеленых тестах — обычное дело с моками.
Ещё раз повторюсь. Моки — инструмент. Если ты молотком пользоваться не умеешь и постоянно попадаешь по пальцам, то правильным решением будет научиться пользоваться молотком, а не продолжать закручивать гвозди отвёрткой.

P>·>Моки это всего лишь механизм передачи данных от одного участка кода другому. Пюрешки могут использовать только передачу параметров и возвращаемое значение. Моки — дополнительно позволяют передавать инфу через вызовы методов. Вот и вся разница.

P>Не вся — моки могут добавлять то чего в природе нет, не водится, или выворачивать наизнанку. Соответствие моков реальному поведению системы всегда остаётся на совести разработчика, а следовательно человеческий фактор в его максимальном проявлении.
В параметры тоже можно передавать то чего в природе нет. И что?

P>>>Обмазываетесь моками — значит время на разработку тестов больше, тк тесты хрупкие.

P>·>Моки лишь дополнительный инструмент. Можно им всё сломать, а можно сделать красиво.
P>У вас моки стали какой то панацеей. Вас послушать так у моков одни преимущества, без каких либо недостатков.
Это твои фантазии.

P>>>Моки это инструмент решения проблем, а не способ выражения намерений. А раз так, то нужно сперва решить проблему, тогда и отпадет необходимость применять этот инструмент.

P>·>Решения каких проблем?
P>Зависимости. Моки отрезают зависимости во время тестирования. Что характерно, моки далеко это не единственный инструмент решения этой поблемы, и далеко не самый эффективный.
Ты так и не показал как ты предлагаешь решать эту проблему, только заявил, что решается одной строчкой, но не показал как. Проигнорировал вопрос дважды: Напиши однострочный интеграционный тест для tryAcceptComposition.

P>А у вас он стал панацеей

Не панацеей, а конкретным решением твоей конкретной проблемы.

P>>>Эти вещи связаны исключительно конкретным пайплайном. А вот логически это разные вещи. Тестировать сам пайплайн удобнее интеграционными тестам — прогнал один, значит пайпалайн работает. А вот отдельные части пайплайна — дешовыми юнит-тестами, их можно настрочить тыщи, хоть генерируй по спеке, время на запуск все равно 0 секунд.

P>·>Я о чём и говорю. Шило на мыло меняешь, правда ценой удвоения количества кода.
P>Если есть выбор, моком или простым юнит-тестом, то юнит-тест всегда эффективнее.
Классика же — у каждой проблемы есть простое, ясное, эффективное, но неправильное решение.

P>Удвоение количества — это как раз про моки. При одинаковом покрытии кейсов мокам нужно больше кода.

Я говорю конкретно о статье. Там кол-во кода удвоилось. Тестовое покрытие упало в несколько раз, зато Без Моков™.

P>·>Варианта чего? Вынести пюрешку можно банальным extract method refactoring и покрыть отдельно — если это имеет хоть какую-то практическую пользу. Мой поинт в том, что в статье практической пользы делать закат вручную мне не удалось увидеть.

P>Так вы хотели, что бы вам в трех словах все тайны мироздания раскрыли? Все статьи такие, что там можно найти частный случай и заткнуть всё сразу.
Я хотел, чтобы мне разъяснили нераскрытый вопрос в статье.

P>·>Я предлагаю использовать ооп. На минутку — что требует бизнес? Реализацию сущности MaitreD.

P>Нет, не требует. Бизнесу до ваших сущностей никакого дела нет. А потому разработчик имеет право выбирать, нужна ли ему такая сущность, и как он её будет моделировать — объектами, классами, актерами итд итд итд Хоть набором переменных, абы это имело практическое обоснование
Ясен пень, можно хоть на brainfuck писать, без этого вашего ООП. Но чем модель ближе — тем лучше. ООП как раз направлено на моделирование бизнес-требований как можно более похожим образом — именованная сущность там — именованная сущность здесь. Набор переменных это круто, конечно, но обычно только как практическое обоснование для жоп-секьюрити.

P>·>В статье на замену предложено вычленить локальное нутро реализации метода, вынести наружу, чтобы получилось вот это: int -> (DateTimeOffset -> Reservation list) -> (Reservation -> int) -> Reservation — это вообще чо??!.

P>Это описание конкретного пайплайна. В ооп подходе у вас будет примерно такая же штукенция. Покрасивее будет, т.к. именованая. Но принципиально всё сохранится. В том и то и бенефит.
Какова цель этой штуки? Зачем нам описывать конкретный пайплайн? Что можно полезного делать с этим описанием? Как проверить, что писание верное? Откуда взялось, что "принципиально всё сохранится"?

P>Проблема с самой статье

P>1. в ооп стоит делать так, как автор показывает для фп варианта — больше контроля, меньше моков, больше юнит-тестов
И кода стало больше, и бОльшая часть нетривиального кода не протестирована.

P>2. если в фп задаться целью сделать как автор для ооп вариана — можно просто убиться

А какой целью надо задаваться-то?

P>Это правило для работы с глубокоми иерахиями чего угодно — глубокую запутанную превращаем в плоскую одноуровневую. методы становятся длиннее, но зависимостями управлять легче тк иерархия неглубокая.

Ну так внедрение зависимостей DI+CI это и есть плоская иерархия. В конструкторе все зависимости, методы — целевая бизнес-логика. В статье это и было показано, что такой подход эквивалентен частичному применению функций — код под капотом идентичный получается.

P>>> Вы по прежнему думаете, что моки избавляют от интеграционных тестов. Ровно наоборот — сверх обычных юнитов вам надо понаписывать моки на все кейсы, и всё равно придется писать интеграционные тесты.

P>·>Зачем писать моки на все кейсы? Моки делаются не для кейсов, а для зависимостей. Тут одна зависимость — репозиторий — значит один мок. Неважно сколько кейсов.
P>Ваш мок должен поддерживать все эти кейсы, что очевидно. Думаете мок сам догадается, какие кейсы ему поддерживать?
Ещё раз повторюсь — мок это лишь способ передачи данных внуть метода. В твоём случае ровно то же придётся делать, но передавать через параметры, а не через мок, вот и вся разница.

P>·>Юнит-тестов нужно только два — успешная и неуспешная резервация. Интеграционный тест только один — что MaitreD успешно интегрируется со всеми своими зависимостями.

P>Юнит-тестов нужно гораздо больше — в зависимости от того, сколько у нас параметров, состояний итд.
Сосредоточься на обсуждаемой теме. Я говорю конкретно о коде в статье. Там видно сколько конкретно параметров, состояний и т.д.

P>>>На основе коротких функций мы можем менять компоновку уже по ходу пьесы подстраиваясь под изменения треботваний, а не бетонировать код на все времена.

P>·>"зарезервировать столик" — это Responsibility выполняемое Actor-ом MaitreD. Это понятно бизнесу.
P>Бизнесу до этого никакого дела нет. MaitreD это абстракция уровня реализации.
Слова Responsibility и Actor — это из словаря FRD. Т.е. именно эта терминология используется бизнесом для общения с девами.

P>·>Ты не отвлекайся. Код в статье рассматривай. Расскажи куда там воткнуть это всё в tryAcceptComposition или куда там получится. Я хочу рассмотреть пример когда у метода будет больше одной зависимости. А ты мне предлагаешь зависимости внедрять неявно через аннотации и глобальные переменные.

P>Это ваши фантазии. Я ничего не предлагаю внедрать неявно, тем более с глобальными переменными. Это вы с голосами в голове спорите.
Аннотации именно так и работают.

P>·>Ужас. annotation-driven development. Прям Spring, AOP, ejb, 00-е, application container, framework, middleware. Закопай обратно.

P>Это то куда идут по большому счету все платформы.
Когда отдают на аутсорс в индию, да. Именно такое рассуждение я как-то слышал "у нас требование покрытия тестами >90%. Аннотации в покрытии не участвуют. Давайте программировать на аннотациях".