1 / 24

Refactoring & Testability

Refactoring & Testability. Testing in OOP programming. No life in flexible methodologies and for refactoring-infected developers without SOME kind of AUTOMATED tests Tests are not a panacea, don't be categorical and skeptic. Tremendous use when possible to write

heidi-sosa
Download Presentation

Refactoring & Testability

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Refactoring & Testability

  2. Testing in OOP programming • No life in flexible methodologies and for refactoring-infected developers without SOME kind of AUTOMATED tests • Tests are not a panacea, don't be categorical and skeptic. Tremendous use when possible to write • JUnit is a tool, so "не забивайте гвозди штангенциркулем" • Unit testing forces as to refactor!!!

  3. Unit testing benefits (1 of 2) • Can be applied to incomplete application • JUnit is the first User of your code! • Kinds of tests Unit->Integration->Function->Stress • Characteristic is the amount of application build already • Makes me confident that I prevent my peer developers and QAs from finding tedious errors in my code. • Less code to debug under test (as opposed to functional tests)

  4. Unit testing benefits (2 of 2) • Can simulate errors • Test not only successful path (as integration test basically does), but the scenario when something can fail! • Testing exceptions • Can act as a perfect and up-to-date documentation • Encourage us for refactoring! Probably the most important advantage.

  5. Example. Testing exceptions: try { methodWhichThrowsException(); fail(“Description”); } catch(ApplicationException meaningfulNameExpected) { assertNotNull(“Explanation why expected”,expected) }

  6. Mocking • Programming on interfaces vs. concrete classes • Subclassing from concrete classes is a testing smell • If I subclass and override a method, what do I actually test? • MockObjects.com (JMock) • No! business logic. The mock should 100% comply to contract under CURRENT test. JMock is well suited for this rule.

  7. Example: • Testing e-mail service.

  8. When to use mocks • Notes on page 4

  9. Too many mocks? Hard to setup a test? • Mock lower OR refactor! • If a big framework has single but very smart method doWork() it's most likely a bad idea to test it • Test may be skipped if the method's contract is based solely on other contracts

  10. Example: • Shopping cart test • (com.luxoft.tests.exercises.shoppingcart)

  11. Refactoring • Hardness to write (set up) unit tests FORCES us to simplify (factorize) the method or class or module. • Bad code is impossible to well unit test! • there is one-to-one dependency between good code and ability to write good tests • Code smells (detect manually or by means of PMD, etc.) • Writing tests

  12. Refactoring DON’Ts (1 of 3) • Make Your Own Dependencies • Heavy Duty Constructors • Depend on Concrete Classes • Conditional Slalom. if-branches and switch statements • Depend on Large Context Objects • Use Statics • Use Global Flags

  13. Refactoring DON’Ts (2 of 3) • Use Singletons Everywhere • Use Primitives Wherever Possible • Look for Everything You Need (Law of Demeter) • Couple functional code directly to the external systems it depends on • Mix Object Lifecycles • Side Effects

  14. Refactoring DON’Ts (3 of 3) • Create Utility Classes and Functions/Methods • Create Managers and Controllers • Do Complicated Creation Work in Objects • Utils! • Final Methods • Handcuff your users to Specific Types • Use static initializes

  15. Example. Don’t depend on Large Context Objects: class Mechanic { Engine engine; Mechanic(Context context) { this.engine = context.getEngine(); } }

  16. Example. Violate the law of Demeter: class Monitor { SparkPlug sparkPlug; Monitor(Context context) { this.sparkPlug = context. getCar().getEngine(). getPiston().getSparkPlug(); } }

  17. Inversion of controls & objects construction • Hollywood principle vs. factory method principle • Collaboration graph and construction graph • Remove new operators from application code as much as possible • Conclusion: separate classes with business logic and factories which create classes

  18. Example. Avoid new op. for testability: class House { private final Kitchen kitchen = new Kitchen(); private boolean isLocked; private boolean isLocked() { return isLocked; } private boolean lock() { kitchen.lock(); isLocked = true; } }

  19. Benefits of IoC • Allows us to mock in tests • Allows us to use single instance of a class (saves us memory) • Shortens the methods and make them more precise (only business logic). • Real isolation.

  20. Inversion of controls. Conclusion • It’s good both for tests and for code’s health to: • separate the business logic from factory code to create required objects (for that business logic) • Doing so is really boring! Let the computer do boring stuff. • Use IoC containers • Dependency injection (wiring) • Use empty, param-less constructors. Use setters!

  21. Refactoring for testability. Final thoughts • Consider IoC vs. factory method • Example: Isolate system resources getRemoteDataObtainer() • Test coverage and test quality • 100% coverage does not mean that the method is 100% tested. Example. • Test quality measurement tools • Clover • Jester/Muclipse • Oil detector in a car’s engine

  22. When Unit tests are good? (1 of 2) • Continuous and automated • Hudson / Email reports • Fast, easy to run • Written early to force Refactoring and detect design errors • No real opportunity to use integration tests • When code is good writing tests is fun. Should be easy

  23. When tests are good? (2 of 2) • When there a lots of tests!!! • We MOCK a contract, i.e. believe that a mocked method follows the contract. Test that! • Test as less code outside of the method under test as possible. • Ideally: • test=(test_method_code) + (private_methods) + (mocks)

  24. Unit tests is a must activity for a developer • Unit tests are not even a way to test code, but for a developer is a very much a way to develop perfect code • Just try!

More Related