real world tdd + dependency injection

Post on 23-Feb-2016

65 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

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 - PowerPoint PPT Presentation

TRANSCRIPT

Real world TDD + Dependency Injection

Rob Fonseca-EnsorDatacom Systems

Introductions• I’m Rob Fonseca-Ensor• From Datacom (www.datacom.co.nz)

www.robfe.com

rob@robfe.com

www.twitter.com/robfe

Agenda• 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

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

What is TDD

1. Write a test for whatever feature you’re about to develop

2. Ensure the test fails (important)3. Develop the feature4. Ensure the test passes (also important)

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

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

Starting out with TDD

http://xunitpatterns.com/Goals%20of%20Test%20Automation.html

Learning curve

Sweet

Test Maintenance

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

TDD: Easy and Hard examplesdouble Total(Expense[] es)• Specification:

1. Iterate through all the expenses

2. Add up the “Amount”3. Return the result

• No dependencies• Logic is the same all the

time• Easy to inspect result

void Claim(Expense e)• Specification:

1. All valid claims should be saved2. If a claim is over $200, send an email to the

receptionist3. 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

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”

IOC ExampleNO IOCpublic class Alerter{ public void Alert(string recipient) { SmtpEmailer e = new SmtpEmailer(); e.SendMail( recipient, "Danger", "High voltage!"); }}

WITH IOCpublic class Alerter{ private IEmailer emailer;

public Alerter(IEmailer emailer) { this.emailer = emailer; }

public void Alert(string recipient) { emailer.SendMail( recipient, "Danger", "High voltage!"); }}

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

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

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

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

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

“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

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

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

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

Other DI frameworks• Ninject

– Excellent “Dojo”– High performance for transient components– Well designed extensibility

• Castle’s AOP support can be plugged in• And more!

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 DIhttp://msdn.microsoft.com/en-ca/magazine/cc337885.aspx

• The Ninject Dojo (good theory)http://ninject.org/learn

Questions?

top related