Обновить
26
ApeCoder@ApeCoder

Разработчик

6
Подписчики
Отправить сообщение

Сделать recording enhancement который будет записывать факт применения enhancement внутри себя. Вне зависимости от того, сколькими и какими вызовами это было сделано.

"Только то, что нужно" должно иметь имя интерфейса

То есть если какое-то подмножество интерфейса используется чаще, то надо его выделять и использовать и фейкать.

Для оставшихся мы используем тот же симулятор, только создаем его уже в залогиненом виде
ИЛИ используем другой ограниченный интерфейс со своим симулятором

Затем, чтобы протестировать вот эти требования:
•SUT должен логиниться с credentials, полученными из конфигурации
•на каждый успешный логин должен быть логаут
•если логин неуспешен, отправка (и вообще никакие действия с нотификатором) не осуществляется

Напишите требования к SUT использующие данные методы, а я скажу, зачем

Для тех, кто зависит от логина реализация нужна, значит мы ее делаем.
Для тех кто не зависит от логина, предоставляем factory method InMemorySender.CreateLoggedInSender() и не тащим подробности логина и логаута в их тесты.


Тестировать надо его реализацию, очевидно.

Это да.

Если нам нужен очень редко Login и Logout надо просто сделать интерфейс, который не содержит их

Э нет. С точки зрения технологии они нужны. Просто для тестируемых бизнес-сценариев они неинтересны.

Я ж не говорю убрать существующий интерфейс, где они есть


Который тоже придется тестировать, ага.

Это интерфейс, что его тестировать?

http://xunitpatterns.com/Shared%20Fixture.html


We reuse the same instance of the test fixture across many tests.

То есть если новый экземпляр симулятора создавать отдельно для каждого теста, он не будет shared fixture

Если нам нужен очень редко Login и Logout надо просто сделать интерфейс, который не содержит их и в большинстве случаев используется именно он. Возможно даже стоит выделить LoggedInSender чтобы система типов контролировала, что либо классу передали залогиненый сендер, либо он сам залогинен.

Проверяет-проверяет. Просто не прямо, а косвенно.

Ок можете истолковывать мое "не проверять вызовы" как "проверять вызовы, но только так, чтобы все корректные с точки зрения абстракции вызовы считались тестом корректными. Или в максимальной степени соответствовать этому условию"


Симулятор — часть тестов. Поэтому тесты изменятся.

Ок, не придется менять каждый конкретный тест, придется менять только общую для всех часть в симуляторе

Если это не полная реализация, значит это реализация не этого интерфейса, а какого-то его подмножества.


И как только какой-то метод где-нибудь в глубине начнет использовать что-то выходящее за это подмножество куча тестов могут посыпаться.


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

Фейк должен поддерживать только то, что нужно от "Реального объекта" и это "Только то, что нужно" должно иметь имя интерфейса

Чтобы снизить стоимость реализации надо применять hexagonal architecture и required interface на границах. То есть если у вас есть файловая система, а вам надо использовать только одну папку с файлами, и от нее интересно только поиск по имени и чтение содержимого, надо делать абстракцию BlobStorage с реализацией FolderBlobStorage и InMemoryBlobStorage и не симулировать всякие там атрибуты и прочее

Оно не проверяет. Допустим у нас поменяется интерфейс. Вместо sendNotification будет


startSendNotification, addTextPath, endSendNoptification


Тесты не изменятся — он будет предоставлять notifier и ожидать что результатом будет отправленное собщение. Изменятся только реализация и симулятор.


То есть у SUT контракт "если вы мне предоставите notifier я туда пошлю сообщение" а тест "вот тебе notifier а я проверяю сообщения" и таким образом тест проверяет контракт, а все подробности релизации скрыты в симуляторе и в SUT

Сделать фейк (можно вслед за Арло назвать это симулятором пока я не разберусь с определением :)) который позволяет работать с результатом действий и создавать и работать быстро и, таким образом, не шарить между тестами

Ну и чем это отличается от того, что написано в посте как нежелательное?

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


Количество этих тестов обусловлено только и исключительно тем, какой модуль вы тестируете. Если вам надо
протестировать кэширующий декоратор, то у вас большая часть тестов будет именно такой.

Да именно так.

Вы правы, я перепутал. У Фаулера


Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).
Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it 'sent', or maybe only how many messages it 'sent'.
Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.

Я бы сделал считающий декоратор для абстракции (интересно, можно автоматом сгенерить). Это весьма специфичные тесты и я бы постарался делать такие тесты как можно меньше

А почему нам не интересны конкретные операции со строкой (а интересен результат) но такое нельзя применить с другими абстракциями.


Не станут ли тесты более стабильными, если такой же принцип применять к другим абстракциям?

Если делать нотифаер моком, то тест будет хрупкий — зависеть от последовательности вызова методов и прочее.

Что??

Mock подразумевает canned response — то есть если меня вызвали два раза на первый я возвращаю это а на второй то и еще проверяю что в первый раз аргументы такие, в другой другие, нет?

Информация

В рейтинге
Не участвует
Откуда
Россия
Дата рождения
Зарегистрирован
Активность