Pull to refresh

Comments 13

я его использую только для наименования тестов. Так из названия тестов хорошо видно, что именно тест тестирует - привык🤷‍♂️

Нижнее подчёркивание действительно принято использовать в именах тестов, но чаще всего им отделяют три компонента названия: объект тестирования (например метод), сценарий и ожидаемое поведение, например:

[Fact]
public void Add_SingleNumber_ReturnsSameNumber()
{
    var stringCalculator = new StringCalculator();

    var actual = stringCalculator.Add("0");

    Assert.Equal(0, actual);
}

Взято отсюда https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices#follow-test-naming-standards

а не лучше вот так? : settingsProvider.Setup(x => x.Get(It.IsAny<string>())).Returns(0);

да, во втором тесте забыл поправить (в реальном коде метод называется GetValue и кроме ключа, там второй аргумент - дефолтное значение, которое возвращается в случае, если настройки нет). Поправил, спасибо

Хорошая статья, но режет глаз наследование ImageCacheMiddlewareForTesting для тестов. ASP.NET Core middleware поддерживает Constructor Injection — можно просто инжектить ISettingsProvider напрямую, без виртуальных методов и наследников. Тогда и тесты станут чище, и продакшен-код не придётся менять ради тестирования. А в остальном — подход через middleware годный, спасибо!

спасибо за совет, попробую. Если правильно помню, что-то не завелось через constructor injection именно в middlewares. Это первое, что я пробую обычно, т.к. самый простой и наиболее логичный путь. Для ViewComponents напр. construction injwction завелся, а для middlewares почему-то нет. Но я пробовал это на более ранних версиях MVC Core - тогда нашел рабочий вариант с HttpContext.RequestServices.GetService<T>() и так его и использую с тех пор. Вообщем посмотрю, спасибо👍

Я не люблю смешивать функциональные и нефункциональные аспекты, поэтому буду использовать третий вариант с промежуточным слоем.

Не совсем понятен этот тезис. У вас контроллер и есть то место, которое целиком и полностью отвечает только за http запросы. То,что делается одним атрибутом (вариант 1) или вариант 2 с возможностью читать срок жизни кэша из настроек, вы размазали в избыточные строки кода. Кроме того, ваш промежуточный слой сейчас кэширует вообще все ответы, а это значит что его нужно доработать, добавив в код if условия и, вероятно, связность с нужным контроллером, чтобы понимать нужно кэшировать или нет.

Upd. Увидел, что эту связность вы запихнули вообще в самое неподходящее место - в use. Код стал плохо поддерживаемый.

>Не совсем понятен этот тезис. У вас контроллер и есть то место, которое целиком и полностью отвечает только за http запросы.

При чем здесь http запросы? Я писал про смешивание функциональных и нефункциональных аспектов внутри контроллера. Функциональные аспекты - то что относится к основной деятельности контроллера (в данном случае, работа с картинками - операции с их созданием, удалением, масштабированием и др), нефункциональные - обвязка вокруг функциональных (логирование, кеширование, обработка транзакций и др).


> Кроме того, ваш промежуточный слой сейчас кэширует вообще все ответы, а это значит что его нужно доработать, добавив в код if условия и, вероятно, связность с нужным контроллером, чтобы понимать нужно кэшировать или нет.

все ответы из action-а под названием View, чего и нужно было добиться



> Upd. Увидел, что эту связность вы запихнули вообще в самое неподходящее место - в use. Код стал плохо поддерживаемый.

по-моему, это наиболее подходящее место для подобных вещей, чтобы оставить код контроллера "чистым". Согласен, что с таким подходом, глядя на action View, сразу сложно сказать, что его результат кэшируется - у себя я решил это добавлением однострочного комментария над action-ом. Но если вам этот подход не нравится, можете использовать другие - для этого я их и упомянул

Вы видимо неправильно понимаете границы ответственности работы контроллеров в ASP. То, что вы пишите "в данном случае, работа с картинками - операции с их созданием, удалением, масштабированием и др" - это, извините меня, ответственность не котроллера, а доменного слоя. Контроллер - это порт из терминологии про луковую\ортодоксальную архитектуру, и никакую бизнес логику содержать не может. Про токний\ходой контроллер и про его потомка в виде minimal API слышали же? Представим, что завтра у вас появляется новый канал связи с клиентами: шина, web socket, gRPC и т.д. Вы операции работы с файлами все будете туда копировать? Контроллер отвечает за полный цикл взаимодействия между доменной логикой и её потребителями, в том числе и за управление кэшированием, т.к. это нефункциональные требования канала.

>>нефункциональные - обвязка вокруг функциональных (логирование, кеширование, обработка транзакций и др).

О как интересно. По вашему, в сервис нельзя инжектить (вы же надеюсь против DI ничего не имеете?) ILogger и потом его там вызывать, ведь это же нефункциональные возможности, а не бизнес логика?

А авторизацию (подчёркиваю, авторизацию) вы как делаете у себя, раз у вас неприязнь к атрибутам?

А такие нефункциональные требования как "система должна отвечать не более чем за 3 секунды" - это обвязка над чем? У вас какое-то свое вольное трактование требований.

>>все ответы из action-а под названием View, чего и нужно было добиться

А если, а точнее когда, мне нужно будет сделать разные правила кэширования, например, видео на 1 неделю, изображения на 20 дней, а аватары пользователей - вообще не кэшировать, вы это как делать будете в своем одном месте управления "аспектом кэширования"? Ну понятно, наставите if'ов. А потом у вас и тесты будут структурированы не по доменной зоне, а по аспектной. Сомнительно, ну ок, если вам так нравится.

>>Но если вам этот подход не нравится

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

И при этом, ладно бы, придумали что-то новое, но нет, отказались от общепринятых решений в пользу костылей. Или вы наверное хотите сказать, что архитекторы из майкрософт, которые дали нам такие возможности, дураки и ошибаются, а вы... А вы распространяете вредные советы, надеюсь жуны (кои еще остались) и обучающие датасеты ИИ не возьмут в серьёз ваше решение.

Вы видимо неправильно понимаете границы ответственности работы контроллеров в ASP. То, что вы пишите "в данном случае, работа с картинками - операции с их созданием, удалением, масштабированием и др" - это, извините меня, ответственность не котроллера, а доменного слоя

во первых, полноценный доменный слой не всегда нужен: частно достаточно внутри вызвать метод соответствующего репозитория (про паттерн репозиторий же слышали? Как встречный вопрос по DI :) ). Во-вторых, в моей статье ни о каких шинах, web socketах, gRPC и т.д речь не идет. Не надо натягивать сову на глобус.

По вашему, в сервис нельзя инжектить

где про это говорится в статье?

ILogger и потом его там вызывать, ведь это же нефункциональные возможности, а не бизнес логика?

волне себе можно, я так и делаю, когда других возможностей нет. Да смешивание, да не нравится, но приходится делать. Там, где можно избежать прямого использования ILogger, стараюсь избегать. Мир - это не черное и белое

А авторизацию (подчёркиваю, авторизацию) вы как делаете у себя, раз у вас неприязнь к атрибутам?

авторизацию делаю аттрибутами - там это вполне оправдано (см. предыдущий ответ)

А такие нефункциональные требования как "система должна отвечать не более чем за 3 секунды" - это обвязка над чем?

требование к производительности, именно что нефункциональное

А если, а точнее когда, мне нужно будет сделать разные правила кэширования, например, видео на 1 неделю, изображения на 20 дней

опять попытка натянуть сову на глобус

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

по-моему, наоборот - сложность увеличивается если смешивать все аспекты в одну кучу

Последний абзац комментировать не буду, неконструктивно.

Я вам понял, вы решили свою свою маленькую задачу, решили в лоб, архитектурная расширяемость вас не интересует. Ну на этом и остановимся 🤷‍♂️

опять фантазии, не имеющие ничего общего с реальностью🤷‍♂️

Sign up to leave a comment.

Articles