1 / 24

Real world TDD + Dependency Injection

Real world TDD + Dependency Injection. Rob Fonseca-Ensor Datacom Systems. I’m Rob Fonseca-Ensor From Datacom (www.datacom.co.nz) www.robfe.com rob@robfe.com www.twitter.com/robfe. Introductions. Unit testing & TDD How Inversion of Control helps you TDD

damali
Download Presentation

Real world TDD + Dependency Injection

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. Real world TDD + Dependency Injection Rob Fonseca-Ensor Datacom Systems

  2. I’m Rob Fonseca-Ensor From Datacom (www.datacom.co.nz) www.robfe.com rob@robfe.com www.twitter.com/robfe Introductions

  3. Unit testing & TDD How Inversion of Control helps you TDD How Dependency Injection helps you IOC Build your own DI container Using the Microsoft Unity container Other DI containers Agenda

  4. Plain Old Unit Testing • Verification of isolated “units” of code • Automated • Self-Verifying • Repeatable • Just call a method and check its results • Linear • Easy to read • MsUnit is built into most versions of Visual Studio • Open source frameworks available too

  5. What is TDD • Write a test for whatever feature you’re about to develop • Ensure the test fails (important) • Develop the feature • Ensure the test passes (also important)

  6. Why TDD • Increased code coverage (Same as POUT?) • Refactorable • Understandable (better than comments) • Better code design (TDD only) • Forces a conscious design of method signatures • Requirements problems will be raised sooner • Code complex functionality faster (TDD only) • Start small, and make little improvements • Positive reinforcement at every step • Faster "code - compile - check" cycle

  7. Why TDD Saves Time • You can fix bad code without worry • Just run the tests after “fixing” it • You can understand code faster • The tests offer a verifiable narrative • Play with the code and see what breaks • It’s easier to build the code in the first place • The code will be better designed • Business requirements • Software structure

  8. Starting out with TDD Learning curve Test Maintenance Sweet http://xunitpatterns.com/Goals%20of%20Test%20Automation.html

  9. When does TDD hurt? • Very low level • Check that a property setter works • Too slow to develop • Often pointless • Very high level / coarse functions • Too hard to develop • Often useful (but treat them as “Integration Tests”) • External dependencies / process boundaries • Too fragile • Too slow to run

  10. TDD: Easy and Hard examples double Total(Expense[] es) void Claim(Expense e) Specification: All valid claims should be saved If a claim is over $200, send an email to the receptionist If the person’s total claims for the month are over $1000, send an email to the receptionist Depends on Database Email infrastructure Logic is tied to data Data query is tied to logic Don’t call db if claim not valid No return value Where’s the result • Specification: • Iterate through all the expenses • Add up the “Amount” • Return the result • No dependencies • Logic is the same all the time • Easy to inspect result

  11. How IOC helps TDD • Usually, a component will “new” up whatever it needs to get the job done • SqlConnection / OracleConnection • SmtpClient • HttpWebRequest • With IOC, the component is no longer in control of what its dependencies are • It should interact with its dependencies through interfaces, instead of directly via classes • Tests can substitute test doubles in place of real dependencies • Mocks, Stubs etc • Mock objects will let you test components from both ends of the stack! • AKA GOF “Strategy Pattern”

  12. IOC Example NO IOC WITH IOC public class Alerter { private IEmailer emailer; public Alerter(IEmailer emailer) { this.emailer = emailer; } public void Alert(string recipient) { emailer.SendMail( recipient, "Danger", "High voltage!"); } } public class Alerter { public void Alert(string recipient) { SmtpEmailer e = new SmtpEmailer(); e.SendMail( recipient, "Danger", "High voltage!"); } }

  13. Other advantages of IOC • MUCH easier to write “Single Responsibility” classes • Easy to swap out implementations • Adding features • Different flavour of database • New web service API • Install-specific customisation • Different business rule modules per site • Easy to reuse existing code • Services can be chained • AuditingRepository wraps IRepository

  14. IOC in production • Dependency hierarchies need to be built • Web page depends on ILogic • Logic depends on IRepository (data access) • Logic depends on IEmailer • Repository depends on IDBConnection • Hand coding a hierarchy gets tiresome • Especially if you have to swap a dependency

  15. Dependency Injection • A framework to provide concrete implementations to your components • Single point of configuration • *.config • Global.asax • Program.cs • Should handle dependency chains / hierarchies

  16. Demo: DIY DI • Lets build our own DI container • See how they work • Simple container: • Supports registering types • Supports resolving types • Sub-dependencies are resolved too • See www.kenegozi.com

  17. DIY DI • Don’t want to download and package yet another DLL? • Paste my code into your app • Upgrade when you need to • Watch my blog for a bigger (50 line) DI container • Support for named parameters • Support for component lifestyles • Transient / Singleton

  18. “Proper” DI Containers • More features than we’ve just covered: • Error handling • Named parameters • Property/Method injection • AOP • Configuration • XML • Fluent • Ease of use • Performance • Reflection vs. Dynamic MSIL generation • Component pooling

  19. Microsoft Unity • http://www.codeplex.com/unity • MS-PL License • Built on ObjectBuilder • Better at “injection” • Configuration is simpler • More lightweight • Lots of videos! Check out the website • Might be part of .Net one day

  20. Unity Demo • What the app does • The service interfaces used • The tests • The components • The components’ unity bits • Global.asaxconfig

  21. Other DI frameworks • Castle Windsor • Mature • Widely used • Excellent AOP support • Comes with my personal stamp of approval • 2 projects in production with Castle • Spring .Net • Mature • Widely used • Excellent AOP support

  22. Other DI frameworks • Ninject • Excellent “Dojo” • High performance for transient components • Well designed extensibility • Castle’s AOP support can be plugged in • And more!

  23. Links • Testing patterns (good theory) http://xunitpatterns.com • Scott’s roundup http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx • A bigger D.I.Y. DI container (coming soon) http://www.robfe.com • James Kovacs’ MSDN Article on DI http://msdn.microsoft.com/en-ca/magazine/cc337885.aspx • The Ninject Dojo (good theory) http://ninject.org/learn

  24. Questions?

More Related