SlideShare a Scribd company logo
Breaking Dependencies
to Allow UnitTesting
Steve Smith
Ardalis Services
@ardalis | ardalis.com
Tweet Away
• LiveTweeting and Photos are encouraged
• Questions and Feedback are welcome
• Use #DevIntersection and/or #breakDependencies
• Or #DevIntersectionBreakingDependenciesToAllowUnitTesting (55 chars with space)
Pluralsight
I have some 1-month free
passes; see me after if
you’d like one
Questions up Front
What kinds of dependencies in your code cause you the most pain today?
Legacy Code
“To me, legacy code is simply code without tests.”
Michael Feathers
Working Effectively with Legacy Code
UnitTesting (Legacy) Code is…
Here’s (Mostly)Why…
Hollywood made a whole movie about it…
But let’s back up…
• Why UnitTests?
• Why not just use other kinds of tests?
• What are dependencies?
• How do we break these dependencies?
UnitTests Prevent SmallThermal Exhaust Ports inYour Code
UnitTest Characteristics
• Test a single unit of code
• A method, or at most, a class
• Do not test Infrastructure concerns
• Database, filesystem, etc.
• Do not test “through” the UI
• Just code testing code; no screen readers, etc.
UnitTests are (should be) FAST
• No dependencies means
1000s of tests per second
• Run them constantly
UnitTests are SMALL
• Testing one thing should be simple
• If not, can it be made simpler?
• Should be quick to write
UnitTest Naming
• Descriptive And Meaningful Phrases (DAMP)
• NameTest Class: ClassNameMethodName
• NameTest Method: DoesSomethingGivenSomething
• http://ardalis.com/unit-test-naming-convention
Seams
• Represent areas of code where pieces can be decoupled
• Testable code has many seams; legacy code has few, if any
Kinds ofTests
UI
IntegrationTests
UnitTests
http://martinfowler.com/bliki/TestPyramid.html
Ask yourself:
•Can I test this scenario with a UnitTest?
•Can I test it with an IntegrationTest?
• Can I test it with an automated UITest?
UI
Integration Tests
UnitTests
Don’t believe your test runner…
IntegrationTest
UnitTest?
• Requires a database or file?
• Sends emails?
• Must be executed through the UI?
Not a unit test
Dependencies and Coupling
All dependencies point toward
infrastructure
Presentation
Layer
Business Layer
Infrastructure
Data Access
Tests
Tests (and everything else) now
depend on Infrastructure
Dependency Inversion Principle
High-level modules should not depend on low-level modules. Both should
depend on abstractions.
Abstractions should not depend on details. Details should depend on
abstractions.
Agile Principles, Patterns, and Practices in C#
Depend on Abstractions
All dependencies point
toward Business Logic /
CorePresentation Layer
Business Layer
Infrastructure
DataAccess
UnitTests
IntegrationTestsUITests
Inject Dependencies
• Classes should follow Explicit Dependencies Principle
• http://deviq.com/explicit-dependencies-principle
• Prefer Constructor Injection
• Classes cannot be created in an invalid state
https://flic.kr/p/5QsGnB
Common Dependencies to Decouple
•Database
•File System
•Email
•Web APIs
•System Clock
•Configuration
•Thread.Sleep
•Random
Tight Couplers: Statics and new
• Avoid static cling
• Calling static methods with side effects
• Remember: new is glue
• Avoid gluing your code to a specific implementation
• Simple types and value objects usually OK
http://ardalis.com/new-is-glue
Coupling Code Smells
• Learn more in my Refactoring Fundamentals course on Pluralsight
• http://www.pluralsight.com/courses/refactoring-fundamentals
• Coupling Smells introduce tight coupling between parts of a system
Feature Envy
• Characterized by many getter calls
• Violates the “Tell, Don’tAsk” principle
• Instead, try to package data and behavior together
• Keep together things that change together
• Common Closure Principle – Classes that change together are packaged together
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Law of Demeter
• Or the “StronglyWorded Suggestion of Demeter”
• A Method m on an object O should only call methods on
• O itself
• m’s parameters
• Objects created within m
• O’s direct fields and properties
• Global variables and static methods
Law of Demeter
Law of Demeter
Law of Demeter
http://geek-and-poke.com
Constructors
Explicit Dependencies Principle
• Methods and classes should require their collaborators as parameters
• Objects should never exist in an invalid state
http://deviq.com/explicit-dependencies-principle/
Constructor Smells
• new keyword (or static calls) in constructor or field declaration
• Anything more than field assignment!
• Database access in constructor
• Complex object graph construction
• Conditionals or Loops
Good Constructors
• Do not create collaborators, but instead accept them as parameters
• Use a Factory for complex object graph creation
• Avoid instantiating fields at declaration
“
”
IoC Containers are just factories on
steroids.
Don’t be afraid to use them where they can help
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Avoid Initialize Methods
• Moving code out of the constructor and into Init()
• If called from constructor, no different
• If called later, leaves object in invalid state until called
• Object has too many responsibilities
• If Initialize depends on infrastructure, object will still be hard to test
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
“Test” Constructors
• “It’s OK, I’ll provide an “extra” constructor my tests can use!”
• Great! As long as we don’t have to test any other classes that use the other
constructor.
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Avoid Digging into Collaborators
• Pass in the specific object(s) you need
• Avoid using “Context” or “Manager” objects to access additional
dependencies
• Violates Law of Demeter: Context.SomeItem.Foo()
• Suspicious Names: environment, principal, container
• Symptoms:Tests have mocks that return mocks
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Avoid Global State Access
• Singletons
• Static fields or methods
• Static initializers
• Registries
• Service Locators
Singletons
• Avoid classes that implement their own lifetime tracking
• GoF Singleton Pattern
• It’s OK to have a container manage object lifetime and enforce having only a
single instance of a class within your application
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies inWeb Forms
Demo
Answer Questions
Demo
Summary
• Inject Dependencies
• Remember “New is glue”.
• Keep yourAPIs honest
• Remember the Explicit Dependencies Principle.Tell your friends.
• Maintain seams and keep coupling loose
Thanks!
• Questions?
• Follow me at @ardalis
• Check out http://DevIQ.com for more on these topics
• Take Pride inYour Code!
• References
• http://misko.hevery.com/code-reviewers-guide/
• Working Effectively with Legacy Code
by Michael Feathers
Please use Event Board
to fill out a session evaluation.

More Related Content

What's hot (20)

PPTX
Automated Acceptance Tests in .NET
Wyn B. Van Devanter
 
PDF
Getting Started with Selenium
Dave Haeffner
 
PDF
Selenium Frameworks
Dave Haeffner
 
PDF
How To Use Selenium Successfully
Dave Haeffner
 
PPTX
Working Effectively With Legacy Code
Excella
 
PPTX
Power-Up Your Test Suite with OLE Automation by Joshua Russell
QA or the Highway
 
PPTX
Testing Java EE apps with Arquillian
Ivan Ivanov
 
PDF
Selenium Users Anonymous
Dave Haeffner
 
PDF
Software Engineering - chp7- tests
Lilia Sfaxi
 
PPT
Acceptance Test Driven Development With Spec Flow And Friends
Christopher Bartling
 
PDF
Unit testing - A&BP CC
JWORKS powered by Ordina
 
PDF
How To Find Information On Your Own
Dave Haeffner
 
PDF
Getting Ahead of Delivery Issues with Deep SDLC Analysis by Donald Belcham
.NET Conf UY
 
PPTX
Bdd and spec flow
Charles Nurse
 
PPTX
Testable requirements
Wyn B. Van Devanter
 
PPTX
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...
seleniumconf
 
PPTX
Automated Acceptance Test Practices and Pitfalls
Wyn B. Van Devanter
 
PPTX
Как стать синьором
COMAQA.BY
 
PDF
TDD and BDD and ATDD
Anuar Nurmakanov
 
PDF
Behavior Driven Development with SpecFlow
Rachid Kherrazi
 
Automated Acceptance Tests in .NET
Wyn B. Van Devanter
 
Getting Started with Selenium
Dave Haeffner
 
Selenium Frameworks
Dave Haeffner
 
How To Use Selenium Successfully
Dave Haeffner
 
Working Effectively With Legacy Code
Excella
 
Power-Up Your Test Suite with OLE Automation by Joshua Russell
QA or the Highway
 
Testing Java EE apps with Arquillian
Ivan Ivanov
 
Selenium Users Anonymous
Dave Haeffner
 
Software Engineering - chp7- tests
Lilia Sfaxi
 
Acceptance Test Driven Development With Spec Flow And Friends
Christopher Bartling
 
Unit testing - A&BP CC
JWORKS powered by Ordina
 
How To Find Information On Your Own
Dave Haeffner
 
Getting Ahead of Delivery Issues with Deep SDLC Analysis by Donald Belcham
.NET Conf UY
 
Bdd and spec flow
Charles Nurse
 
Testable requirements
Wyn B. Van Devanter
 
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...
seleniumconf
 
Automated Acceptance Test Practices and Pitfalls
Wyn B. Van Devanter
 
Как стать синьором
COMAQA.BY
 
TDD and BDD and ATDD
Anuar Nurmakanov
 
Behavior Driven Development with SpecFlow
Rachid Kherrazi
 

Similar to Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016 (20)

PDF
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014
FalafelSoftware
 
PPTX
Introduction to Dependency Injection
SolTech, Inc.
 
PPTX
I gotta dependency on dependency injection
mhenroid
 
PDF
Mock Objects, Design and Dependency Inversion Principle
P Heinonen
 
PPTX
Unit testing
Panos Pnevmatikatos
 
PDF
Unit Testing Fundamentals
Richard Paul
 
PPTX
Unit tests & TDD
Dror Helper
 
PPTX
Rc2010 tdd
JasonOffutt
 
PPTX
Building unit tests correctly
Dror Helper
 
PPTX
Cut your Dependencies with Dependency Injection - .NET User Group Osnabrueck
Theo Jungeblut
 
PPTX
Test Driven Development:Unit Testing, Dependency Injection, Mocking
mrjawright
 
PPTX
Using Boundary-Driven Development to beat code complexity
Dennis Doomen
 
PPTX
Refactoring Applications using SOLID Principles
Steven Smith
 
PPTX
Cut your Dependencies - Dependency Injection at Silicon Valley Code Camp
Theo Jungeblut
 
PPTX
Chapter 7 achieving object-oriented design
Sergio Andrés Rodríguez Galeano
 
PPTX
Unit Testing
Sergey Podolsky
 
PDF
Testing: ¿what, how, why?
David Rodenas
 
PDF
(automatic) Testing: from business to university and back
David Rodenas
 
PPTX
Real Life Unit Testing
Dror Helper
 
PPTX
Architecting, testing and developing an mvc application
Maxime Rouiller
 
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014
FalafelSoftware
 
Introduction to Dependency Injection
SolTech, Inc.
 
I gotta dependency on dependency injection
mhenroid
 
Mock Objects, Design and Dependency Inversion Principle
P Heinonen
 
Unit testing
Panos Pnevmatikatos
 
Unit Testing Fundamentals
Richard Paul
 
Unit tests & TDD
Dror Helper
 
Rc2010 tdd
JasonOffutt
 
Building unit tests correctly
Dror Helper
 
Cut your Dependencies with Dependency Injection - .NET User Group Osnabrueck
Theo Jungeblut
 
Test Driven Development:Unit Testing, Dependency Injection, Mocking
mrjawright
 
Using Boundary-Driven Development to beat code complexity
Dennis Doomen
 
Refactoring Applications using SOLID Principles
Steven Smith
 
Cut your Dependencies - Dependency Injection at Silicon Valley Code Camp
Theo Jungeblut
 
Chapter 7 achieving object-oriented design
Sergio Andrés Rodríguez Galeano
 
Unit Testing
Sergey Podolsky
 
Testing: ¿what, how, why?
David Rodenas
 
(automatic) Testing: from business to university and back
David Rodenas
 
Real Life Unit Testing
Dror Helper
 
Architecting, testing and developing an mvc application
Maxime Rouiller
 
Ad

More from Steven Smith (20)

PPTX
Clean architecture with asp.net core by Ardalis
Steven Smith
 
PDF
Finding Patterns in the Clouds - Cloud Design Patterns
Steven Smith
 
PPTX
Introducing domain driven design - dogfood con 2018
Steven Smith
 
PPTX
Introducing Domain Driven Design - codemash
Steven Smith
 
PPTX
Most Useful Design Patterns
Steven Smith
 
PPTX
Improving the Design of Existing Software
Steven Smith
 
PPTX
Introducing ASP.NET Core 2.0
Steven Smith
 
PPTX
Decoupling with Domain Events
Steven Smith
 
PPTX
A Whirldwind Tour of ASP.NET 5
Steven Smith
 
PPTX
Domain events
Steven Smith
 
PPTX
My Iraq Experience
Steven Smith
 
PDF
Add Some DDD to Your ASP.NET MVC, OK?
Steven Smith
 
PDF
Domain-Driven Design with ASP.NET MVC
Steven Smith
 
PPTX
Refactoring with SOLID Principles (FalafelCon 2013)
Steven Smith
 
PPTX
Common ASP.NET Design Patterns - Telerik India DevCon 2013
Steven Smith
 
PPTX
Refactoring with SOLID - Telerik India DevCon 2013
Steven Smith
 
PPTX
Common asp.net design patterns aspconf2012
Steven Smith
 
PPTX
Common design patterns (migang 16 May 2012)
Steven Smith
 
PDF
Introducing Pair Programming
Steven Smith
 
PPTX
Cinci ug-january2011-anti-patterns
Steven Smith
 
Clean architecture with asp.net core by Ardalis
Steven Smith
 
Finding Patterns in the Clouds - Cloud Design Patterns
Steven Smith
 
Introducing domain driven design - dogfood con 2018
Steven Smith
 
Introducing Domain Driven Design - codemash
Steven Smith
 
Most Useful Design Patterns
Steven Smith
 
Improving the Design of Existing Software
Steven Smith
 
Introducing ASP.NET Core 2.0
Steven Smith
 
Decoupling with Domain Events
Steven Smith
 
A Whirldwind Tour of ASP.NET 5
Steven Smith
 
Domain events
Steven Smith
 
My Iraq Experience
Steven Smith
 
Add Some DDD to Your ASP.NET MVC, OK?
Steven Smith
 
Domain-Driven Design with ASP.NET MVC
Steven Smith
 
Refactoring with SOLID Principles (FalafelCon 2013)
Steven Smith
 
Common ASP.NET Design Patterns - Telerik India DevCon 2013
Steven Smith
 
Refactoring with SOLID - Telerik India DevCon 2013
Steven Smith
 
Common asp.net design patterns aspconf2012
Steven Smith
 
Common design patterns (migang 16 May 2012)
Steven Smith
 
Introducing Pair Programming
Steven Smith
 
Cinci ug-january2011-anti-patterns
Steven Smith
 
Ad

Recently uploaded (20)

PDF
10 Salesforce Consulting Companies in Sydney.pdf
DianApps Technologies
 
PDF
Notification System for Construction Logistics Application
Safe Software
 
PPTX
Get Started with Maestro: Agent, Robot, and Human in Action – Session 5 of 5
klpathrudu
 
PDF
Code and No-Code Journeys: The Maintenance Shortcut
Applitools
 
PDF
Instantiations Company Update (ESUG 2025)
ESUG
 
PDF
chapter 5.pdf cyber security and Internet of things
PalakSharma980227
 
PDF
Windows 10 Professional Preactivated.pdf
asghxhsagxjah
 
PPTX
How Odoo ERP Enhances Operational Visibility Across Your Organization.pptx
zidanakhtar874
 
PPTX
API DOCUMENTATION | API INTEGRATION PLATFORM
philipnathen82
 
PPTX
iaas vs paas vs saas :choosing your cloud strategy
CloudlayaTechnology
 
PPTX
leaf desease detection using machine learning.pptx
kdjeevan35
 
PDF
custom development enhancement | Togglenow.pdf
aswinisuhu
 
PDF
ERP Consulting Services and Solutions by Contetra Pvt Ltd
jayjani123
 
PPTX
Operations Profile SPDX_Update_20250711_Example_05_03.pptx
Shane Coughlan
 
PPTX
Transforming Lending with IntelliGrow – Advanced Loan Software Solutions
Intelli grow
 
PDF
Simplify React app login with asgardeo-sdk
vaibhav289687
 
PDF
Understanding the EU Cyber Resilience Act
ICS
 
PPTX
Smart Doctor Appointment Booking option in odoo.pptx
AxisTechnolabs
 
PPTX
Odoo Migration Services by CandidRoot Solutions
CandidRoot Solutions Private Limited
 
PDF
Australian Enterprises Need Project Service Automation
Navision India
 
10 Salesforce Consulting Companies in Sydney.pdf
DianApps Technologies
 
Notification System for Construction Logistics Application
Safe Software
 
Get Started with Maestro: Agent, Robot, and Human in Action – Session 5 of 5
klpathrudu
 
Code and No-Code Journeys: The Maintenance Shortcut
Applitools
 
Instantiations Company Update (ESUG 2025)
ESUG
 
chapter 5.pdf cyber security and Internet of things
PalakSharma980227
 
Windows 10 Professional Preactivated.pdf
asghxhsagxjah
 
How Odoo ERP Enhances Operational Visibility Across Your Organization.pptx
zidanakhtar874
 
API DOCUMENTATION | API INTEGRATION PLATFORM
philipnathen82
 
iaas vs paas vs saas :choosing your cloud strategy
CloudlayaTechnology
 
leaf desease detection using machine learning.pptx
kdjeevan35
 
custom development enhancement | Togglenow.pdf
aswinisuhu
 
ERP Consulting Services and Solutions by Contetra Pvt Ltd
jayjani123
 
Operations Profile SPDX_Update_20250711_Example_05_03.pptx
Shane Coughlan
 
Transforming Lending with IntelliGrow – Advanced Loan Software Solutions
Intelli grow
 
Simplify React app login with asgardeo-sdk
vaibhav289687
 
Understanding the EU Cyber Resilience Act
ICS
 
Smart Doctor Appointment Booking option in odoo.pptx
AxisTechnolabs
 
Odoo Migration Services by CandidRoot Solutions
CandidRoot Solutions Private Limited
 
Australian Enterprises Need Project Service Automation
Navision India
 

Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016

  • 1. Breaking Dependencies to Allow UnitTesting Steve Smith Ardalis Services @ardalis | ardalis.com
  • 2. Tweet Away • LiveTweeting and Photos are encouraged • Questions and Feedback are welcome • Use #DevIntersection and/or #breakDependencies • Or #DevIntersectionBreakingDependenciesToAllowUnitTesting (55 chars with space)
  • 3. Pluralsight I have some 1-month free passes; see me after if you’d like one
  • 4. Questions up Front What kinds of dependencies in your code cause you the most pain today?
  • 5. Legacy Code “To me, legacy code is simply code without tests.” Michael Feathers Working Effectively with Legacy Code
  • 8. Hollywood made a whole movie about it…
  • 9. But let’s back up… • Why UnitTests? • Why not just use other kinds of tests? • What are dependencies? • How do we break these dependencies?
  • 10. UnitTests Prevent SmallThermal Exhaust Ports inYour Code
  • 11. UnitTest Characteristics • Test a single unit of code • A method, or at most, a class • Do not test Infrastructure concerns • Database, filesystem, etc. • Do not test “through” the UI • Just code testing code; no screen readers, etc.
  • 12. UnitTests are (should be) FAST • No dependencies means 1000s of tests per second • Run them constantly
  • 13. UnitTests are SMALL • Testing one thing should be simple • If not, can it be made simpler? • Should be quick to write
  • 14. UnitTest Naming • Descriptive And Meaningful Phrases (DAMP) • NameTest Class: ClassNameMethodName • NameTest Method: DoesSomethingGivenSomething • http://ardalis.com/unit-test-naming-convention
  • 15. Seams • Represent areas of code where pieces can be decoupled • Testable code has many seams; legacy code has few, if any
  • 17. Ask yourself: •Can I test this scenario with a UnitTest? •Can I test it with an IntegrationTest? • Can I test it with an automated UITest? UI Integration Tests UnitTests
  • 18. Don’t believe your test runner… IntegrationTest
  • 19. UnitTest? • Requires a database or file? • Sends emails? • Must be executed through the UI? Not a unit test
  • 20. Dependencies and Coupling All dependencies point toward infrastructure Presentation Layer Business Layer Infrastructure Data Access Tests Tests (and everything else) now depend on Infrastructure
  • 21. Dependency Inversion Principle High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions. Agile Principles, Patterns, and Practices in C#
  • 22. Depend on Abstractions All dependencies point toward Business Logic / CorePresentation Layer Business Layer Infrastructure DataAccess UnitTests IntegrationTestsUITests
  • 23. Inject Dependencies • Classes should follow Explicit Dependencies Principle • http://deviq.com/explicit-dependencies-principle • Prefer Constructor Injection • Classes cannot be created in an invalid state https://flic.kr/p/5QsGnB
  • 24. Common Dependencies to Decouple •Database •File System •Email •Web APIs •System Clock •Configuration •Thread.Sleep •Random
  • 25. Tight Couplers: Statics and new • Avoid static cling • Calling static methods with side effects • Remember: new is glue • Avoid gluing your code to a specific implementation • Simple types and value objects usually OK http://ardalis.com/new-is-glue
  • 26. Coupling Code Smells • Learn more in my Refactoring Fundamentals course on Pluralsight • http://www.pluralsight.com/courses/refactoring-fundamentals • Coupling Smells introduce tight coupling between parts of a system
  • 27. Feature Envy • Characterized by many getter calls • Violates the “Tell, Don’tAsk” principle • Instead, try to package data and behavior together • Keep together things that change together • Common Closure Principle – Classes that change together are packaged together
  • 30. Law of Demeter • Or the “StronglyWorded Suggestion of Demeter” • A Method m on an object O should only call methods on • O itself • m’s parameters • Objects created within m • O’s direct fields and properties • Global variables and static methods
  • 36. Explicit Dependencies Principle • Methods and classes should require their collaborators as parameters • Objects should never exist in an invalid state http://deviq.com/explicit-dependencies-principle/
  • 37. Constructor Smells • new keyword (or static calls) in constructor or field declaration • Anything more than field assignment! • Database access in constructor • Complex object graph construction • Conditionals or Loops
  • 38. Good Constructors • Do not create collaborators, but instead accept them as parameters • Use a Factory for complex object graph creation • Avoid instantiating fields at declaration
  • 39. “ ” IoC Containers are just factories on steroids. Don’t be afraid to use them where they can help
  • 44. Avoid Initialize Methods • Moving code out of the constructor and into Init() • If called from constructor, no different • If called later, leaves object in invalid state until called • Object has too many responsibilities • If Initialize depends on infrastructure, object will still be hard to test
  • 47. “Test” Constructors • “It’s OK, I’ll provide an “extra” constructor my tests can use!” • Great! As long as we don’t have to test any other classes that use the other constructor.
  • 49. Avoid Digging into Collaborators • Pass in the specific object(s) you need • Avoid using “Context” or “Manager” objects to access additional dependencies • Violates Law of Demeter: Context.SomeItem.Foo() • Suspicious Names: environment, principal, container • Symptoms:Tests have mocks that return mocks
  • 52. Avoid Global State Access • Singletons • Static fields or methods • Static initializers • Registries • Service Locators
  • 53. Singletons • Avoid classes that implement their own lifetime tracking • GoF Singleton Pattern • It’s OK to have a container manage object lifetime and enforce having only a single instance of a class within your application
  • 58. Summary • Inject Dependencies • Remember “New is glue”. • Keep yourAPIs honest • Remember the Explicit Dependencies Principle.Tell your friends. • Maintain seams and keep coupling loose
  • 59. Thanks! • Questions? • Follow me at @ardalis • Check out http://DevIQ.com for more on these topics • Take Pride inYour Code! • References • http://misko.hevery.com/code-reviewers-guide/ • Working Effectively with Legacy Code by Michael Feathers Please use Event Board to fill out a session evaluation.

Editor's Notes

  • #3: https://twitter.com/hashtag/devintersection https://twitter.com/hashtag/breakdependencies Set low expectations
  • #6: And specifically, we want fast, automated tests.
  • #8: Developers like to build things, but often the way they connect parts of an application together (if there even are separate parts) is like using super glue. Good luck testing the interface of one building block.
  • #9: If you haven’t seen it yet, you should. This guy wants to use krazy glue to keep anything from changing. Probably not how we want our software to be designed.
  • #10: I want to answer these questions in this session. 1. 2. 3.
  • #14: …unless the system is difficult to break apart
  • #15: Avoid names that provide no information: CustomerTests Test1 Test2 Test3
  • #16: PC (seams) vs. MAC (no seams) PC – Power supply goes bad. Solution: Order new power supply, open case, replace. MAC – Power supply goes bad. Solution: Buy a new Mac.
  • #17: Because they’re small and fast, you should have a lot of unit tests. They should be the foundation of your testing approach. Integration tests can include tests of services that sit between different layers of your application. Defense in Depth These aren’t the only kinds of tests
  • #18: Test at the lowest level you can, since that will be the least expensive test to write, run, and maintain.
  • #19: ReSharper calls any test you run a unit test, regardless of what kind of test it actually is.
  • #20: Also, they shouldn’t be terribly complex, slow, or involve more than one or two classes.
  • #21: Dependencies are transitive. If A depends on B and B depends on C, then A depends on C. When I talk about breaking dependencies, I’m also talking about reducing coupling. Loosely coupled code can be tested more easily, since there are fewer connections to have to break apart, and they’re easier to swap out.
  • #29: This can be difficult to test, especially if either of the two classes in question are difficult to set up in a particular state. To fix this, move the behavior where it belongs.
  • #30: This can of course be refactored further to eliminate the conditional complexity, using inheritance or a compositional pattern.
  • #31: “Well, the code is more like guidelines than rules.” Assume as little as possible about collaborators’ collaborators Law of Demeter is not just about having two many dots in an expression.
  • #32: Imagine when you order a pizza, the delivery person uses code like this to get paid. Does this seem to model how things actually work? Should the delivery person have access to your wallet and its contents? What if you don’t have a wallet? This code is now tightly coupled not only to a Customer, but to a Wallet and its implementation.
  • #33: What if instead the Customer could respond to requests for payment, like this? Note that wallet is no longer exposed outside of the Customer class.
  • #34: At this point, the original code makes a bit more sense. Payment is requested, and how it is achieved is no longer a concern of the calling code. Payment can come from a money clip, purse, or from under a mattress and this code will still work. Testing this code could use a simplified fake customer and wouldn’t require implementation of both a fake customer and a fake wallet, making test code simpler. Reduce coupling – keep your classes from having to know too much about the details of their collaborators.
  • #35: Drink water
  • #38: Constructors should be extremely simple. They shouldn’t choose the object’s collaborators, or how the object is retrieved from persistence. These things violate the Single Responsibility Principle for the constructor’s class, and tightly couple the class to certain implementation details. Constructors that accept collaborators provide seams – hard-coding collaborators erases such seams. New is probably OK for initializing simple things like strings, datetimes, or collections to avoid nulls. Prefer the new C# 6 syntax for this with properties.
  • #39: Note, it’s fine to create simple types and value objects – simply consider whether it’s making the object harder to test or not when deciding.
  • #41: This code is difficult to test and tightly coupled to a dbContext, which in this case probably makes it impossible to test this code without a database.
  • #42: Note that in this case the only thing the constructor does is assign parameters to fields, and no fields are instantiated as part of their declaration.
  • #43: Likewise, avoid making static lookup calls or assignments within a constructor, especially ones that depend on infrastructure or the local environment. Avoid depending on configuration directly – remember it’s a dependency.
  • #44: The solution is the same – avoid creating things in the constructor in favor of passing these things in. If you can’t pass in the thing itself, pass in a means of getting to it (like we’re doing with IConfig in this case), but keep it simple as possible.
  • #47: Dependency injection again saves the day. The initialization logic is a separate responsibility from whatever the service does, and so belongs in another class.
  • #53: Adds coupling in an invisible, hard to track manner. Makes testing difficult, especially parallel testing or testing in any order Causes Spooky Action at a Distance – your method causes some unexpected behavior in some other part of the system
  • #55: Third party library with static call
  • #56: Use a wrapper and inject