А почему в понятие "квадрат" входит операция "изменить размеры и остаться квадратом". Не может ли быть квадратных констант? Не может ли (теоретически) квадрат перестать быть квадратом?
По вашему, это свойство ООП как такового, или скорее популярных языков? В каком-нибудь self или vba нет вообще никаких классов. Может быть можно придумать (или уже придумали) язык, который
Является OO
Поддерживает параллельную независимую классификацию тех же объектов.
С точки зрения модульности, которая есть ив ФП эта фнукция должна принадлежать какому-то модулю. Почему нельзя этот модуль роассматривать как объект (Game, CollisionProcessingRules, etc..)
У нас весь отдел разработки уходит в отпуск одновременно.
и болеют тоже. А если кто-то попадает под машину расстреливают весь отдел. А если человек загружен задачей и появляется еще одна задача в его области, то соответсвующая часть кода стирается и переписывается.
Предварительно мы приводим инфосистему к стабильному состоянию, в котором она работает без проблем и без постоянной поддержки со стороны разработчиков.
А если все-таки случается инцидент требующий такой поддержки? Вы пишете вообще без ошибок? Срочная задача, например?
Вот мне интересно про VerifyNoOtherCalls — это не приводит к излишней хрупкости теста? Т.е. фактически мы проверяем не только что он делает что-то но и то что он не делает ничего еще — если в будущей появится новое требование мы должны будем переделывать все такие тесты. Что из этого получается на практике?
Еще хотелось бы увидеть общий подход к организации тестов — на какие куски делите, и какими инструментами отслеживаете структуру (сколько уровней категоризации и так далее и насколько устраивает то, что получилось)?
Да блин возможности по композиции в .NET почти безграничны, зачем вам метод createAll.
ну вот вы сделали CreateProduct(ingridient: "olive", amount: 10) потом в другом месте сделали CreateSpecialProduct() а потом с третьем месте понадобилось CreateSpecialProduct(ingridient: "olive", amount: 10) — как вы их скомпозируете? Придется рефакторить.
А ну да обрубок вроде
Method_ShouldWorkAsExpected_WhenGetsRightValue — так это и есть фраза на человеческом языке с точностью до написания. Мы ж все равно ее пишем, чем нам написать еще раз облегчает дело?
Да но ваш service это объект тестирования, так что это сбивает с толку.
Как сбивает? Я же обращение к методу с целью проверки результатов поместил внутрь assert — наоборот, в этом случае Act отделен он Assert если вынести GetReservedAmount в отдельную переменную, придется писать комментарий
// Assert
перед GetReservedAmount. Нет?
Ну это уж вам решать как структурировать код, можно и не в одном методе.
Я имел ввиду, что у вас метод уже создает что-то — соответственно сочетать два таких метода вместе не удастся. Метод не умеет модифицировать уже готовый ордер, например.
Здесь страдает не читаемость кода теста, а ошибки в ходе прогона тестов.
Я тоже про них.
Обычно названия метода-теста выводятся при ошибках, так, что если мы видим что тест проверяет зарезервированность И ошибка в том, что количество отличается от заданного можно сказать что проверяется зарезервированное количество.
Секция 8.3.4 Separating asserts from actions
Я думаю, имелось ввиду action — это то, что мы проверяем, а assert — то, как мы проверяем. В моем коде action это AcceptOrder. Я посмотрел несколько примеров из книжки, там используются выражения и вызовы методов в assert.
Возможно — но тогда придется все сочетания поддерживать в одном методе.
Кстати в той же книге предлагается награждать описанием проверки типа
С моей точки зрения, когда в тесте ровно один ассерт и название достаточно говорящее, это не надо. Кстати.
Не совсем уверен что service.GetReservedAmount(ingridient) и AmountOfProductInOrderLine * AmountOfIngridientInProduct уместны в секции Assert, по книге аrt of unit testing.
В книжке Art of unit testing, предлагается скрывать детали не относящиеся к конкретному тесту и показывать связь между исходными данными и результатами. В получившемся результате скрыто почти все (из кода теста непонятно, что и сколько должно быть зарезервировано). Фактически и CreateDualOrder и VerifyReserveIngredientsWasCalledWith внутри используют какие-то константы но как они друг с другом связаны, неясно.
Я бы написал так:
var ingridient = CreateIngridient();
var product = CreateProduct().WithIngridient(ingridient, AmountOfIngridientInProduct).Please();
var order = CreateOrder().WithLine(product, AmountOfProductInOrderLine).Please();
var service = CreateService();
service.AcceptOrder(order);
Assert.Equals(AmountOfProductInOrderLine * AmountOfIngridientInProduct, service.GetReservedAmount(ingridient));
AutoFixture не пользовался, интересно, как там с воспроизводимостью падений. Например, в данном случае вполне возможно, что результат будет работать с точностью до округлений (каковые будет проверять другой тест).
Я думаю, это скорее зависит от языка, чем от фреймворка.
В случае С# property и collection initializers устраняют некоторую потребность в строителях, но все равно есть потребность в бизнес-специфичных алгоритмах типа "создай заказ готовый для исполнения" когда можно убрать под капот какие-то детали создания, не важные для конкретного теста.
Например, тут я бы убрал дату внутрь билдера:
var order = Create.Order
.With(Pizza.Pepperoni.CountOf(1).For(500))
.With(Pizza.Margarita.CountOf(1).For(650))
.Please();
var service = Create.PizzeriaService.Please();
service.AcceptOrder(order);
service.VerifyReserveIngredientsWasCalledWith(order);
Но, внезапно выясняется, что property и collection initializers работают только при создании объекта.
Т.е. написать new Order{ Date = Today } можно, а CreateOrder(){Date = Today} нельзя.
del
То есть для любого прямоугольника в мире имеет смысл операции "изменение сторон"? Константые прямоугольники или вычисляемые прямоугольники запрещены?
А почему в понятие "квадрат" входит операция "изменить размеры и остаться квадратом". Не может ли быть квадратных констант? Не может ли (теоретически) квадрат перестать быть квадратом?
Вечный цикл покинуть нельзя. Если используется break это значит цикл не вечный, но условие выхода находится где-то унутре
По вашему, это свойство ООП как такового, или скорее популярных языков? В каком-нибудь self или vba нет вообще никаких классов. Может быть можно придумать (или уже придумали) язык, который
С точки зрения модульности, которая есть ив ФП эта фнукция должна принадлежать какому-то модулю. Почему нельзя этот модуль роассматривать как объект (Game, CollisionProcessingRules, etc..)
Подобно тому, как в смолтоке классы тоже объекты
Это нельзя назвать иерархией?

я так понял, borrow checker заставляет следить программиста ;)
и болеют тоже. А если кто-то попадает под машину расстреливают весь отдел. А если человек загружен задачей и появляется еще одна задача в его области, то соответсвующая часть кода стирается и переписывается.
А если все-таки случается инцидент требующий такой поддержки? Вы пишете вообще без ошибок? Срочная задача, например?
Вы, наверное, живете в параллельном мире.
Которую мы положим в файл с каким именем?
Почему менеджер а, не, например, Игра
Если программист уходит в отпуск, и обнаруживают ошибку весь код переписывается. Когда он возвращается — он переписывается обратно.
Сейчас уже есть typescript который потихонечку взлетает и webassembly
Вот мне интересно про VerifyNoOtherCalls — это не приводит к излишней хрупкости теста? Т.е. фактически мы проверяем не только что он делает что-то но и то что он не делает ничего еще — если в будущей появится новое требование мы должны будем переделывать все такие тесты. Что из этого получается на практике?
Еще хотелось бы увидеть общий подход к организации тестов — на какие куски делите, и какими инструментами отслеживаете структуру (сколько уровней категоризации и так далее и насколько устраивает то, что получилось)?
ну вот вы сделали CreateProduct(ingridient: "olive", amount: 10) потом в другом месте сделали CreateSpecialProduct() а потом с третьем месте понадобилось CreateSpecialProduct(ingridient: "olive", amount: 10) — как вы их скомпозируете? Придется рефакторить.
Method_ShouldWorkAsExpected_WhenGetsRightValue — так это и есть фраза на человеческом языке с точностью до написания. Мы ж все равно ее пишем, чем нам написать еще раз облегчает дело?
Как сбивает? Я же обращение к методу с целью проверки результатов поместил внутрь assert — наоборот, в этом случае Act отделен он Assert если вынести GetReservedAmount в отдельную переменную, придется писать комментарий
// Assert
перед GetReservedAmount. Нет?
Я имел ввиду, что у вас метод уже создает что-то — соответственно сочетать два таких метода вместе не удастся. Метод не умеет модифицировать уже готовый ордер, например.
Я тоже про них.
Обычно названия метода-теста выводятся при ошибках, так, что если мы видим что тест проверяет зарезервированность И ошибка в том, что количество отличается от заданного можно сказать что проверяется зарезервированное количество.
Я думаю, имелось ввиду action — это то, что мы проверяем, а assert — то, как мы проверяем. В моем коде action это AcceptOrder. Я посмотрел несколько примеров из книжки, там используются выражения и вызовы методов в assert.
Возможно — но тогда придется все сочетания поддерживать в одном методе.
С моей точки зрения, когда в тесте ровно один ассерт и название достаточно говорящее, это не надо. Кстати.
Почему?
В книжке Art of unit testing, предлагается скрывать детали не относящиеся к конкретному тесту и показывать связь между исходными данными и результатами. В получившемся результате скрыто почти все (из кода теста непонятно, что и сколько должно быть зарезервировано). Фактически и CreateDualOrder и VerifyReserveIngredientsWasCalledWith внутри используют какие-то константы но как они друг с другом связаны, неясно.
Я бы написал так:
AutoFixture не пользовался, интересно, как там с воспроизводимостью падений. Например, в данном случае вполне возможно, что результат будет работать с точностью до округлений (каковые будет проверять другой тест).
Я думаю, это скорее зависит от языка, чем от фреймворка.
В случае С# property и collection initializers устраняют некоторую потребность в строителях, но все равно есть потребность в бизнес-специфичных алгоритмах типа "создай заказ готовый для исполнения" когда можно убрать под капот какие-то детали создания, не важные для конкретного теста.
Например, тут я бы убрал дату внутрь билдера:
Но, внезапно выясняется, что property и collection initializers работают только при создании объекта.
Т.е. написать new Order{ Date = Today } можно, а CreateOrder(){Date = Today} нельзя.
Для записей есть proposal
Можно просто брать и писать, как будто билдеры уже есть, а потом пусть студия создаст недостающие методы.