Ну записала. Это проверило, что сделаны нужные вызовы?
Да. Только эта проверка не должна валится во всех комбинациях вызовов которые допускает интерфейс. Т.е. не должно быть canned response.
Почему?
1) Иначе тесты будут хрупкими. Падение теста будет просто показывать, что изменилось что-то незначительное.
2) В разных тестах будет разная реализация — это значит что реюз кода фейка будет затруднен. А фейк должен поддерживать абстракцию полностью. Иначе тест будет проверять не "Если мы тебе передали нотификатор, то ты долджен отослать сообщения" а "Если мы тебе передали нечто ограниченное не имеющее название и не специфицированное в твоем интерфейсе то ты должен передать сообщение". То есть как только в Notificator появится еще один метод мы должны реализовывать его во всех специфических для тестов нотификаторах
1) Записывать нотификейшены в список в памяти
2) Она не должна знать про конкретный тест и про конкретное использование абстракции в конкретном. То есть если интерфейс позволяет вызывать методы в любом порядке, то и реализация интерфейса должна позволять так.
1) Это не размер, это имя. Размер должен быть какой-то метрикой. Причем оверхед посравнению с моком.
2.1) Да, все правильно будет 2.2 сделанный постепенно
2.2) И что — мы рефакторим Notifier а не тесты.
Если делать нотифаер моком, то тест будет хрупкий — зависеть от последовательности вызова методов и прочее.
Если делать его фейком, то будет стабильная абстракция и тесты не будут валиться при эквивалетных преобразованиях.
Теперь давайте задумаемся, почему мы не мокаем System.String?
Мой ответ такой, что для теста нам нужна полная но самая простая реализация зависимости. Если самая простая реализация зависимости уже есть в production, то можно использовать ее.
Арло Белши, например, где-то писал что фейки могут понадобитьяс в продакшене (например можно собрать какой-нибудь буфер нотификаций используя InMemoryNotificationSender)
Таким образом, с моей точки зрения, если Notificator будет достаточно простым внутри его вполне можно использовать в тесте
new[] { 1, 2, 3 }.Should().Contain(item => item > 3, "at least {0} item should be larger than 3", 1);
Таким образом мы не проверяем каким количеством и каких вызовов получено уведомление. Мы просто проверяем что если передать что-то поддерживающее интерфейс INotifier, то в результате действия мы получаем уведомление.
Надо передавать готовую хорошо сделанную абстракцию (у Фаулера — fake)типа InMemoryNotifier.
Она должна быть не Ad Hoc для теста с записанными количествами вызовов, а реализовывать некий интерфейс
Он запускает программу PowerShell для выполнения комманд,
ISE у меня как правило открыт и комп я перегружаю редко
вспоминает команду для получения списка сервисов Get-Service, затем вспоминает что у неё существует короткое имя,
Не, я просто пишу gsv — для меня gsv это уже непосредственно команда получения статуса сервиса, а вот длинный алиас придется вспоминать
затем приступает к вспоминанию параметров этой команды, набирает ёё и затем анализирует многострочный текстовый результат выполнения. Запуская графическую программу Services, я сразу получаю удобное окно со списком сервисов с описаниями, состояниями, аккаунтами с возможностью сортировки, скроллингом и управлением сервисом.
Оно не очень удобное за счет того, что нет фильтрации как правило личено меня интересуют определенные сервисы, а не список всех.
Да, когда надо отредактировать я иду в gui. Я не говорю, что command line или gui всегда удобнее или неудобнее. Я говорю, что часто даже для выполнения однократной задачи удобнее cli
Дык мы говорим про администрирование, а не про программирование. Нам нет нужды делать так, чтобы эта строчка гарантированно работала на любом окружении. Та же самая проблема будет при поиске сервиса глазом
Вы в качестве примера возьмите что-то для обучения программированию, а не для решения практических задач,
это раз.
Практически любая конструкция в программировании абстракция, это два, просто для вас этот уровень уже пройден и ваш мозг, как и мой живет внутри компьютера. переменные и циклы уже часть нашего мира и для нас они не ощущаются астракциями.
Возможно, стоит тренировать детей программированием — то есть выхлопом должны быть не навыки программирования, а навыки формальной логики и абстрактного мышления, которые они могут использовать и в быту, да и просто для понимания окружения, которое состоит во многом из программ.
Спасибо, я смотрел терминологию у Фаулера и не видел там этого ограничения
Надо перечитать в http://xunitpatterns.com/Using%20Test%20Doubles.html я увидел реализацию In Memory DB, но не увидел примера теста.
Мне надо посмотреть, что именно Мезарос имеет ввиду под Directly Controlled. Вы не можете сделать ссылку yна пример использования Fake у него?
Да. Только эта проверка не должна валится во всех комбинациях вызовов которые допускает интерфейс. Т.е. не должно быть canned response.
1) Иначе тесты будут хрупкими. Падение теста будет просто показывать, что изменилось что-то незначительное.
2) В разных тестах будет разная реализация — это значит что реюз кода фейка будет затруднен. А фейк должен поддерживать абстракцию полностью. Иначе тест будет проверять не "Если мы тебе передали нотификатор, то ты долджен отослать сообщения" а "Если мы тебе передали нечто ограниченное не имеющее название и не специфицированное в твоем интерфейсе то ты должен передать сообщение". То есть как только в Notificator появится еще один метод мы должны реализовывать его во всех специфических для тестов нотификаторах
1) Записывать нотификейшены в список в памяти
2) Она не должна знать про конкретный тест и про конкретное использование абстракции в конкретном. То есть если интерфейс позволяет вызывать методы в любом порядке, то и реализация интерфейса должна позволять так.
Не надо canned response.
1) Это не размер, это имя. Размер должен быть какой-то метрикой. Причем оверхед посравнению с моком.
2.1) Да, все правильно будет 2.2 сделанный постепенно
2.2) И что — мы рефакторим Notifier а не тесты.
Если делать нотифаер моком, то тест будет хрупкий — зависеть от последовательности вызова методов и прочее.
Если делать его фейком, то будет стабильная абстракция и тесты не будут валиться при эквивалетных преобразованиях.
Теперь давайте задумаемся, почему мы не мокаем System.String?
Мой ответ такой, что для теста нам нужна полная но самая простая реализация зависимости. Если самая простая реализация зависимости уже есть в production, то можно использовать ее.
Арло Белши, например, где-то писал что фейки могут понадобитьяс в продакшене (например можно собрать какой-нибудь буфер нотификаций используя InMemoryNotificationSender)
Таким образом, с моей точки зрения, если Notificator будет достаточно простым внутри его вполне можно использовать в тесте
1) Размер оверхеда?
2.1) red — green — refactor
2.2) Resharper
InMemoryNotificationRecorder это InMemory реализайия INotifier которая кладет в себя нотификейшены.
Should.COntain — это из Fluent assertions
Его можно со всеми коллекциями употреблять
Таким образом мы не проверяем каким количеством и каких вызовов получено уведомление. Мы просто проверяем что если передать что-то поддерживающее интерфейс INotifier, то в результате действия мы получаем уведомление.
```С#
Надо передавать готовую хорошо сделанную абстракцию (у Фаулера — fake)типа InMemoryNotifier.
Она должна быть не Ad Hoc для теста с записанными количествами вызовов, а реализовывать некий интерфейс
см.
Я бы использовал peel and slice — notifier должен передаваться либо как аргумент конструктора с дефолтным значением либо как свойство
Мне кажется, вы перешли в режим спора для победы
ISE у меня как правило открыт и комп я перегружаю редко
Не, я просто пишу gsv — для меня gsv это уже непосредственно команда получения статуса сервиса, а вот длинный алиас придется вспоминать
Оно не очень удобное за счет того, что нет фильтрации как правило личено меня интересуют определенные сервисы, а не список всех.
Да, когда надо отредактировать я иду в gui. Я не говорю, что command line или gui всегда удобнее или неудобнее. Я говорю, что часто даже для выполнения однократной задачи удобнее cli
Вы пробовали это на PSh под Linux — если dd это что-то внешнее — а не встроенная команда, почему бы нет?
Дык мы говорим про администрирование, а не про программирование. Нам нет нужды делать так, чтобы эта строчка гарантированно работала на любом окружении. Та же самая проблема будет при поиске сервиса глазом
А какой сервис не содержит этого в имени?
Посмотрите на LINQ
Система типов, .NET FW в качестве основы
Мне кажется, иногда для однократных задач коммандлайн удобнее.
Например в винде — посмотреть на состояние всех сервисов для sql server
А для того, чтобы сделать это из гуя надо открыть приложения сервисов сортировать там по имени и искать глазами
Вы в качестве примера возьмите что-то для обучения программированию, а не для решения практических задач,
это раз.
Практически любая конструкция в программировании абстракция, это два, просто для вас этот уровень уже пройден и ваш мозг, как и мой живет внутри компьютера. переменные и циклы уже часть нашего мира и для нас они не ощущаются астракциями.
Возможно, стоит тренировать детей программированием — то есть выхлопом должны быть не навыки программирования, а навыки формальной логики и абстрактного мышления, которые они могут использовать и в быту, да и просто для понимания окружения, которое состоит во многом из программ.