4. Razones Válidas ¡No se! Código antiguo UI No hacer pruebas Inválidas El diseño es malo De eso se encarga QA No coge los bugs Demasiadas interfaces Es lento Aburido…. Es dificil de cambiar
9. Localización del “new” Otra clase Estímulo Otra clase API de Pruebas Clase bajo prueba Verificaciones Otra clase Instanciado dentro de la clase Pasado por referencias Estados globales
10. Localización del “new” Otra clase Otra clase Otra clase Otra clase Estímulo Otra clase API de Pruebas Clase bajo prueba Otra clase Verificaciones Otra clase
11. Localización del “new” Otra clase Otra clase Otra clase Otra clase Estímulo Otra clase API de Pruebas Clase bajo prueba Costura Otra clase Verificaciones Otra clase
12. Localización del “new” Clase Falsa Estímulo Clase Falsa API de Pruebas Clase bajo prueba Costura Verificaciones Clase Falsa
15. Localización del “new” Clase Falsa Estímulo Clase Falsa API de Pruebas Clase bajo prueba Verificaciones Clase Falsa Instanciado dentro de la clase Pasado por referencias Estados globales
17. House classHouse { Kitchenkitchen = new Kitchen(); Bedroombedroom; publicHouse() { this.bedroom = new Bedroom(); } }
18. House Test classHouseTests { @Test publicvoidimpossibleTestOnIsolation() { // Can’treplaceanything!!! } }
19. Análisis Fácil de instanciar pero… No se puede remplazar nada. Puede ser costoso computacionalmente El diseño está acoplado. Cerrado para extensión.
21. House Test (Refactorizado) classHouseTests { @Test publicvoideasierToTestOnIsolation() { DummyKitchendk = new DummyKitchen(); DummyBedroomdb = new DummyBedroom(); House h = new House(dk,db); // … } }
23. Gardener class Garden { Gardenerjoe; public Garden(Gardenerjoe) { joe.setWorkHours(new TwelveHours()); joe.setBoots(new ExpensiveBoots()); this.joe = joe; } }
24. Análisis Mejor pero… No se pueden remplazar las botas o el horario. La prueba puede tardar (horario de 12h). Necesita el jardinero pero se encarga de configurarlo.
26. ¿Por qué? Construcción de objetos Trabajo en el constructor Estados globales Violaciones de la Ley de Deméter
27. Costo de la construcción Para testear, primero hay que instanciar pero… El trabajo dentro del constructor no tiene “costuras” No se puede sobre escribir. La prueba tiene que saber navegar lo que haya dentro
29. Super Car class Car { Engineengine; public Car(Filefile) { String m = readModelFromCfg(file); engine = new EngineFactory().create(m); } }
30. Super Car Test classCarTest { @Test publicvoidhardToSetupTest() { Filefile = new File(“custom.conf”); Car car = new Car(file); //Asserts... } }
31. Análisis Pasamos un File cuando lo que se necesita es un Engine. Toda prueba que necesite Car requiere eta parafernaria. Accede al sistema de ficheros Lento. No es una prueba unitaria realmente.
32. Super Car (Refactorizado) class Car { Engineengine; @Inject public Car(Engineengine) { this.engine = engine; } }
33. Super Car (Provider) classCarEngineProvider { @Provides EnginegetEngine(EngineFactoryfactory, @EngineModelStringmodel) { returnfactory.create(model); } }
34. Super Car Test (Refactorizado) classCarTest { @Test publicvoideasyToSetupTest() { Engineengine = new FakeEngine(); Car car = new Car(engine); //Asserts... } }
35. ¿Por qué? Construcción de objetos Trabajo en el constructor Estados globales Violaciones de la Ley de Deméter
65. ¿Por qué? Construcción de objetos Trabajo en el constructor Estados globales Violaciones de la Ley de Deméter
66.
67. La ley de Deméter Cada unidad debería tener conocimiento limitado sobre otras unidades: solo unidades “relacionadas de cerca” a la unidad actual. Cada unidad debe de hablar solamente con sus amigos; No hablar con extraños. Habla solamente con tus amigos inmediatos.
68. ServiceLocator Aka. Context, aka. Registry… etc. Mejor que un singleton Al menos el problema está en un solo lugar. Es testeable… pero no muy bonito. Esconde las dependencias reales. Las dependencias hacen el código poco reusable.
72. ServiceLocator ¿Qué otro problema tiene? Mezcla responsabilidades. Buscar y encontrar. Creación Se necesita tener una interface para testear Si dependes de ServiceLocator, dependes de todo lo demás.
74. Análisis Para testear se hace complicado Las dependencias no son las declaradas. Crear rpcclient, entrenarlo para devolver un authenticator, crear un authenticator… Etc.