design for testability as a way to good coding
DESCRIPTION
Design for testability as a way to good coding. Simone Chiaretta Architect, Council of the EU http://codeclimber.net.nz Twitter: @ simonech. December 9 th , 2010. Who the hell am I?. Simone Chiaretta Microsoft MVP ASP.NET ASP Insider Blogger – http://codeclimber.net.nz - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/1.jpg)
Design for testability as a way to good coding
Simone ChiarettaArchitect, Council of the EUhttp://codeclimber.net.nzTwitter: @simonech December 9th, 2010
![Page 2: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/2.jpg)
Who the hell am I?
► Simone Chiaretta► Microsoft MVP ASP.NET► ASP Insider► Blogger – http://codeclimber.net.nz ► Italian ALT.NET UG Founder► OpenSource developer► Climber► All Around Nice Guy
Disclaimer:"The views expressed are purely those of the speaker and may not in any circumstances be regarded as stating an official position of the Council"
![Page 3: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/3.jpg)
What are we going to talk about?
► What is “Good Design”?► Testability requirements?► What is Design for Testability?► What is Dependency Injection?► What is Inversion of Control?► How to do IoC via DI using Ninject?► How to do IoC via DI using Unity?► References
![Page 4: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/4.jpg)
What is Good Design?
![Page 5: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/5.jpg)
What is Good Design
► High Cohesion► Low Coupling► Good Encapsulation
![Page 6: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/6.jpg)
What is Good Design
![Page 7: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/7.jpg)
Solid: Single Responsibility Principle (SRP)
A class should have one, and only one, reason to change.
![Page 8: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/8.jpg)
Solid: Single Responsibility Principle (SRP)“If a class has more then one responsibility, then the responsibilities become coupled. Changes to one responsibility may impair or inhibit the class’ ability to meet the others. This kind of coupling leads to fragile designs that break in unexpected ways when changed.”
-Robert C. Martin
![Page 9: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/9.jpg)
Solid: Single Responsibility Principle (SRP)
Email Sending App
File
Email Sender
Flat File XML File
Email Sending App
![Page 10: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/10.jpg)
sOlid: Open Closed Principle (OCP)
You should be able to extend a classes behavior, without modifying it.
![Page 11: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/11.jpg)
sOlid: Open Closed Principle (OCP)
“Modules that conform to the open-closed principle have two primary attributes.
1. They are “Open For Extension”. This means that the behavior of the module can be extended. That we can make the module behave in new and different ways as the requirements of the application change, or to meet the needs of new applications.
2. They are “Closed for Modification”.The source code of such a module is inviolate. No one is allowed to make source code changes to it.”
- Robert C. Martin
![Page 12: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/12.jpg)
sOlid: Open Closed Principle (OCP)
Email Sender
Flat File XML File
IFileFormat Reader
FileReaderService
![Page 13: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/13.jpg)
soLid: Liskov Substitution Principle (LSP)
Derived classes must be substitutable for their base classes.
![Page 14: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/14.jpg)
soLid: Liskov Substitution Principle (LSP)“If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.”
- Barbara Liskov
![Page 15: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/15.jpg)
soLid: Liskov Substitution Principle (LSP)
Email Sender
Flat File XML File
IFileFormat Reader
FileReaderService
Database Connection
File
Database
![Page 16: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/16.jpg)
soLid: Liskov Substitution Principle (LSP)
Email SenderFlat File
XML File
IFileFormat Reader
FileReaderService
Database
DatabaseReaderService
![Page 17: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/17.jpg)
solId: Interface Segregation Principle (ISP)
Clients should not be forced to depend upon interfaces they don’t use
![Page 18: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/18.jpg)
solId: Interface Segregation Principle (ISP)
“This principle deals with the disadvantages of ‘fat’ interfaces. Classes that have ‘fat’ interfaces are classes whose interfaces are not cohesive. In other words, the interfaces of the class can be broken up into groups of member functions. Each group serves a different set of clients. Thus some clients use one group of member functions, and other clients use the other groups.”
- Robert Martin
![Page 19: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/19.jpg)
solId: Interface Segregation Principle (ISP)
EmailSender
• SendEmail• ReadFile• ReadFromDb
EmailSender
• SendEmail
Database ReaderService
• GetMessageBody
FileReaderService
• GetMessageBody
![Page 20: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/20.jpg)
soliD: Dependency Inversion Principle (DIP)
Depend on abstractions, not on concretions.
![Page 21: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/21.jpg)
soliD: Dependency Inversion Principle (DIP)“What is it that makes a design rigid, fragile and immobile? It is the interdependence of the modules within that design. A design is rigid if it cannot be easily changed. Such rigidity is due to the fact that a single change to heavily interdependent software begins a cascade of changes in dependent modules.”
- Robert Martin
![Page 22: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/22.jpg)
soliD: Dependency Inversion Principle (DIP)
ProcessingService
IMessageInfoRetriever IEmailService
File Reader Service
IFileFormat Reader
Email SenderDatabase Reader Service
Flat File Reader
Xml File Reader
![Page 23: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/23.jpg)
Before and After
Email Sending App
File
EmailProcessingService
IMessageInfoRetriever IEmailSender
IMessageInfo
Retriever
Flat File
XML FileIFileFormat
ReaderFileReaderService
DatabaseDatabaseReaderService
IEmailServiceEmailServiceBefor
eAfter
![Page 24: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/24.jpg)
How to test for “good design”?
► You can’t► Actually you can
Clear?
![Page 25: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/25.jpg)
Testability Requirements
![Page 26: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/26.jpg)
Testability Actors
► System Under Test► Depended On Component► Mock/Fake/Stub
![Page 27: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/27.jpg)
Testability Concepts
► Test just one feature► Indipendency from environment► Indipendency from dependencies► Fast
![Page 28: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/28.jpg)
Design for Testability
![Page 29: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/29.jpg)
Design for Testability = Good Design
► Good design is difficult to measure► Easily testable = Good Design
![Page 30: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/30.jpg)
What is Dependency Injection
![Page 31: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/31.jpg)
Bad Code
Demo:
Hard-Coded Dependencies1-2
![Page 32: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/32.jpg)
The problem of strong coupling
► Rigid – Must change the Climber code to change the Tools he uses
► Fragile – Changes to the Tools can affect the Climbers
► Not Testable – Cannot replace the Tools with a stub/fake when I want to test the Climber in isolation
![Page 33: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/33.jpg)
Better Code
Demo:
Hard-Coded Dependencieswith Interface
3
![Page 34: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/34.jpg)
Still problems
► We have lower coupling but still Climber has to be changed to change tools
![Page 35: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/35.jpg)
Slightly Better Code
Demo:
Hard-Coded Dependencieswith Service Locator
4
![Page 36: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/36.jpg)
Still problems
► Still Climber depends on the Locator► Just moving the problem inside another module
![Page 37: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/37.jpg)
Introducing Dependency Injection
Demo:
Dependency Injectionby Hand
5
![Page 38: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/38.jpg)
Good, isn’t it?
► Climber is always the same, and doesn’t know how to “get” the tools
► The Climber is given the tools he has to use
![Page 39: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/39.jpg)
Dependency Injection
Are we done?
NOT YET!
![Page 40: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/40.jpg)
Introducing Dependency Injection
Demo:
Dependency Injectionby Hand
(more complex)6
![Page 41: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/41.jpg)
Needs Improvements
► Host must know how to assemble dependencies
► We loose encapsulation
![Page 42: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/42.jpg)
What is Inversion of Control
![Page 43: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/43.jpg)
Inversion of Control
Demo:
Inversion of Control7
![Page 44: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/44.jpg)
What we achieved
► Still have DIP► Got encapsulation back► Dependencies are handled by external component
![Page 45: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/45.jpg)
How to configure
► XML► Attributes► Fluent API► all of them
![Page 46: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/46.jpg)
Many IoCC
…
![Page 47: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/47.jpg)
Ninject
![Page 48: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/48.jpg)
The Kernel
► Factory Method on Steroids► Hold the configuration► Returns objects
IKernel kernel = new StandardKernel(new
ClimbingModule());var climber = kernel.Get<Climber>();
![Page 49: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/49.jpg)
Modules
► Modules hold specific configurations► Configuration through Fluent API
Bind<Climber>().ToSelf();Bind<IClimbingTools>().To<QuickDraws>();
![Page 50: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/50.jpg)
Inversion of Control
Demo:
Inversion of Control(complex)
8
![Page 51: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/51.jpg)
Different kinds of Injection
► Constructor Injection► Property Injection► Method Injection► Through Factory Method
![Page 52: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/52.jpg)
Attributes
► Are used to help discriminate injection patterns
[Inject]public IClimbingTools tools {get; set;}
[Inject]public void GetReady(IClimbingTools tools)
![Page 53: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/53.jpg)
Inversion of Control
Demo:
AttributesInjection Patterns
9
![Page 54: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/54.jpg)
Behaviours
► Singleton (Default)► Transient► Per Thread► Per Request► BYO
Bind<Climber>().ToSelf().InTransientScope();Bind<Climber>().ToSelf().InSingletonScope();
![Page 55: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/55.jpg)
Inversion of Control
Demo:
Activation Behaviours10
![Page 56: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/56.jpg)
But there is more...
► Constructor Parameters
► Contextual Binding
► Named Binding
Bind<IClimbingTools>().To<IceScrews>() .WithConstructorArgument("brand",
"Black Diamond");
Bind<IClimbingTools>().To<QuickDraws>().WhenInjectedInto(typeof(SportClimber));
Bind<Climber>().To<SportClimber>().Named("Simone");
climber = kernel.Get<Climber>("Simone");
![Page 57: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/57.jpg)
Inversion of Control
Demo:
Advanced Features11
![Page 58: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/58.jpg)
Finally Some Testing
► No need to use IoC any more (and you should not)
MockTools tools = new MockTools();Climber climber = new Climber(tools);climber.Climb();Assert.IsTrue(tools.Placed);
![Page 59: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/59.jpg)
Finally some Testing
Demo:
Testing12
![Page 60: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/60.jpg)
P&P Unity
![Page 61: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/61.jpg)
Unity
► Microsoft IoC container► Configured via code
► Configured through XML
myContainer .RegisterType<IClimbingTools, QuickDraws>();
<unity><typeAliases> <typeAlias alias="IClimbingTools” type="ClimbDemoIoCUnity.IClimbingTools, ClimbDemoIoCUnity" /> <typeAlias alias="QuickDraws” type="ClimbDemoIoCUnity.Tools.QuickDraws, ClimbDemoIoCUnity" /></typeAliases>
<containers> <container>
<types> <type type="IClimbingTools" mapTo="IceScrews" /></types>
</container></containers></unity>
![Page 62: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/62.jpg)
Unity
Demo:
Unity13
![Page 63: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/63.jpg)
Bonus section: Func
![Page 64: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/64.jpg)
Func
► By Daniel Cazzulino (of Moq fame)► The fastest IoC available► Doesn’t use reflection► Always write factory method
container.Register<IClimbingTools>(c => new QuickDraws());
container.Register(c => new Climber(
c.Resolve<IClimbingTools>()));
![Page 65: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/65.jpg)
Bonus section: Func
Demo:
Func14
![Page 66: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/66.jpg)
IoC inside other hosts
![Page 67: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/67.jpg)
IoC in other hosts
► IoC shines when activation is already delegated to factories– ASP.NET MVC– WCF
► Requires changes in the default “object factory”– ControllerFactory– ServiceHostFactory
![Page 68: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/68.jpg)
IoC in other hosts
Demo:
ASP.NET MVC15
![Page 69: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/69.jpg)
Conclusions
![Page 70: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/70.jpg)
Call for Actions
► Think about a project you worked on► Think about any maintainabily/change issue you had:– Most likely they would have been solved with DI/IoC
► Think how DI/IoC could have helped
![Page 71: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/71.jpg)
Main takeaways
► DI/IoC helps building service oriented applications
► DI/IoC helps managing dependencies► DI/IoC helps bulding highly cohese, loose coupled code while maintaling encapsulation
![Page 72: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/72.jpg)
References► Uncle Bob’s Principle Of Object Oriented
Development: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
► OO Design Principles:http://www.oodesign.com/design-principles.html
► Complete SOLID slides and demo (Derick Bailey): http://www.lostechies.com/media/p/5415.aspx
► Ninject:http://ninject.org/ - v2http://github.com/enkari/ninject/ - v2.2 beta
► p&p Unity: http://unity.codeplex.com/ - v2 (part of EntLib5)
► Funq: http://funq.codeplex.com/
![Page 73: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/73.jpg)
Contacts – Simone Chiaretta
► MSN: [email protected]► Blog:
– English: http://codeclimber.net.nz/– Italian: http://blogs.ugidotnet.org/piyo/
► Twitter: @simonech
73
![Page 74: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/74.jpg)
Questions?
Disclaimer:"The views expressed are purely those of the speaker and may not in any circumstances be regarded as stating an official position of the Council"
![Page 75: Design for testability as a way to good coding](https://reader035.vdocuments.us/reader035/viewer/2022062520/56815fe5550346895dcee903/html5/thumbnails/75.jpg)
Rating
If you liked this talk, please consider rating it:
http://speakerrate.com/talks/5193-design-for-testability-as-a-way-to-good-coding
75 Disclaimer:"The views expressed are purely those of the speaker and may not in any circumstances be regarded as stating an official position of the Council"