Я серьезный сторонник надлежащего тестирования Driven Design или Behavior Driven Design, и я люблю писать тесты. Тем не менее, я продолжаю кодировать себя в угол, где мне нужно использовать 3-5 макетов в конкретном тестовом примере для одного класса. Независимо от того, в каком направлении я начинаю, сверху вниз или снизу вверх, я получаю дизайн, в котором требуется как минимум три сотрудника с самого высокого уровня абстракции.
Может кто-нибудь дать хороший совет, как избежать этой ловушки?
Здесь типичный сценарий. Я создаю виджет, который создает Midget из заданного текстового значения. Это всегда начинается очень просто, пока я не займусь деталями. Мой Виджет должен взаимодействовать с несколькими трудными для тестирования таких вещей, как файловые системы, базы данных и сеть.
Итак, вместо того, чтобы конструировать все это в свой виджет, я создаю сотрудника Bridget. Bridget заботится о половине сложности, базе данных и сети, позволяя мне сосредоточиться на другой половине, которая представляет собой мультимедийную презентацию. Итак, тогда я делаю Gidget, который выполняет мультимедийную пьесу. Все это должно происходить в фоновом режиме, поэтому теперь я включаю Thridget, чтобы это произошло. Когда все сказано и сделано, я получаю виджет, который работает с Thridget, который говорит о Бриджит, чтобы дать результат Gidget.
Поскольку я работаю в CocoaTouch и пытаюсь избежать ложных объектов, я использую шаблон self-shunt, где абстракции над соавторами становятся протоколами, которые мой тест принимает. С 3+ сотрудниками мои тестовые воздушные шары и становятся слишком сложными. Даже использование чего-то типа мошеннических объектов OCMock оставляет меня с рядом сложностей, которые я бы предпочел избежать. Я попробовал обернуть мозг вокруг цепочек последователей (делегаты в B, которые делегируют C и т.д.), Но я не могу этого себе представить.
Edit Взяв пример снизу, предположим, что у нас есть объект, который должен читать/записывать из сокетов и предоставлять возвращенные данные фильма.
//Assume myRequest is a String param...
InputStream aIn = aSocket.getInputStram();
OutputStream aOut = aSocket.getOutputStram();
DataProcessor aProcessor = ...;
// This gets broken into a "Network" collaborator.
for(stuff in myRequest.charArray()) aOut.write(stuff);
Object Data = aIn.read(); // Simplified read
//This is our second collaborator
aProcessor.process(Data);
Теперь вышеуказанное, очевидно, имеет дело с сетевой задержкой, поэтому оно должно быть Threaded. Это вводит абстракцию потока, чтобы вывести нас из практики многопоточных модульных тестов. Теперь имеем
AsynchronousWorker myworker = getWorker(); //here our third collaborator
worker.doThisWork( new WorkRequest() {
//Assume myRequest is a String param...
DataProcessor aProcessor = ...;
// Use our "Network" collaborator.
NetworkHandler networkHandler = getNetworkHandler();
Object Data = networkHandler.retrieveData(); // Simplified read
//This is our multimedia collaborator
aProcessor.process(Data);
})
Простите меня за работу без тестов, но я собираюсь вывести мою дочь на улицу, и я спешу на примере. Идея здесь заключается в том, что я организую сотрудничество нескольких сотрудников из-за простого интерфейса, который будет привязан к событию click button. Таким образом, самый большой тест отражает задачу Sprint, которая говорит, что при нажатии кнопки "Воспроизвести фильм" при нажатии на нее будет воспроизводиться фильм. Edit Давайте обсудим.