Clean Coder Blog SHY AWAY FROM ANY TESTS THAT ARE CLOSE TO THE CORE FUNCTIONALITY UNTIL I HAVE COMPLETELY SURROUNDED THE PROBLEM WITH PASSING TESTS THAT DESCRIBE EVERYTHING BUT THE CORE FUNCTIONALITY blog.cleancoder.com/uncle-bob/2014/11/19/GoingForTheGold.html
the return value, or an exception. (Classic) • Check the state of the object, or the state of a collaborator. (Classic) • Check the object correctly interacts with a collaborator. (Mockist)
Runs all the tests • Contains no duplication • Expresses the intent of the programmer • Minimises the user of classes or methods (The Rules are in the order of importance) REFACTORING
Element) { elements.append(element) } var elementCount: Int { get { return elements.count } } func element(name: String) -> Element? { guard let index = ( elements.indexOf { (element) -> Bool in return element.name == name } ) else { return nil } return elements[index] } func generateIndex() { var index = Element(name: "Index") for element in elements { index.addText(element.name + "\n") } addElement(index) } } ISSUE “Change InMemoryDirectory so that clients can add elements and that the index be maintained.” Guard existing behaviour, before adding new ones.
Element) { elements.append(element) } var elementCount: Int { get { return elements.count } } func element(name: String) -> Element? { guard let index = ( elements.indexOf { (element) -> Bool in return element.name == name } ) else { return nil } return elements[index] } func generateIndex() { var index = Element(name: "Index") for element in elements { index.addText(element.name + "\n") } addElement(index) } } generateIndex elements addElement getElement getElementCount newElement addText newElement.name creates struct Element { var name: String mutating func addText(text: String) { name = name + text } }
• SENSING “WE BREAK DEPENDANCIES TO SENSE WHEN WE CAN’T ACCESS VALUES OUR CODE COMPUTES” • SEPARATION “WE BREAK DEPENDANCIES TO SEPARATE WHEN WE CAN’T EVEN GET A PIECE OF CODE INTO A TEST HARNESS TO RUN”