SESSION DETAILS
• 10-15 MINUTES OF BACKGROUND • 50-55 MINUTES OF HANDS-ON CODING
SESSION DETAILS: YOU NEED THIS STUFF
• SEED CODE IS WRITTEN IN C#
• GET IT FROM GITHUB:
https://github.com/KatasForLegacy
...
LEGACY
EXPECTATION REALITY
LEGACY
PERCEPTION - COBOL
LEGACY
PERCEPTION - COBOL REALITY – CODE W/O UNIT TESTS
DEPENDENCY
EXPECTATION REALITY
DEPENDENCY – THE HORRID TRUTH
KILLER
EXPECTATION
“
”
I’VE COMPLETELY SLAUGHTERED ALL THE
LEGACY DEPENDENCIES IN OUR
CODEBASE.
NOW I’LL ENJOY SOME LUNCH.
KILLER
EXPECTATION REALITY
PUT IT ALL TOGETHER & WHADDAYA GET
•A CODE KATA
• A CODE KATA IS AN EXERCISE IN PROGRAMMING
WHICH HELPS A PROGRAMMER HONE ...
DEPENDENCY KATA
• DEPENDENCY KATA: CODE CAMP EDITION
• WRITTEN IN C#
• NOW WITH LESS TOOL DEPENDENCIES AND RESTRUCTURED TO...
DEPENDENCY KATA: INITIAL STRUCTURE
DEPENDENCY KATA: FIRST THINGS FIRST
• LET’S START BY GETTING THE EXISTING TEST
RUNNING
• RUNNING THE INTEGRATION TEST SHOW...
DEPENDENCY KATA: FIRST THINGS FIRST
• IMPLEMENT METHOD TO HANDLE THE DEPENDENCY
public class ConsoleAdapter :
IConsoleAdap...
DEPENDENCY KATA: FIRST THINGS FIRST
• NOW WE HAVE SOME BROKEN INSTANTIATIONS
• IN THE CONSOLE APP INSTANTIATE AND PASS IN
...
DEPENDENCY KATA: FIRST THINGS FIRST
• WHEN THE TEST IS RUN WE NOW GET A
MEANINGFUL EXCEPTION. ALL OF THE
DEPENDENCIES THAT...
DEPENDENCY KATA: FIRST THINGS FIRST
• WHEN THE TEST IS RUN WE NOW GET A
MEANINGFUL EXCEPTION. ALL OF THE
DEPENDENCIES THAT...
DEPENDENCY KATA: BETTER COVERAGE
• WE DON'T HAVE COVERAGE SOME OF THE CODE
STILL AND NO QUANTIFIABLE RESULTS TO TEST
• LET...
DEPENDENCY KATA: BETTER COVERAGE
• NOW CREATE VARIABLES TO HOLD THE MESSAGES
AT VARIOUS POINTS FOR RETURN
private const st...
DEPENDENCY KATA: BETTER ABSTRACTION
• DO WORK TO ABSTRACT CONSOLE COMPLETELY
COMPLETELY
• ADD A NEW METHOD STUB TO
IConsol...
DEPENDENCY KATA: REFACTOR
• DoItAll.Do() IS TRYING TO DO TOO MUCH
• EXTRACT LOGGING FUNCTIONALITY BY CREATING
A NEW INTERF...
DEPENDENCY KATA: REFACTOR
• CLIENT NO LONGER BUILDS BECAUSE OF THE
UPDATED CONSTRUCTOR SO UPDATE IT
• NOW CREATE A NEW FAK...
DEPENDENCY KATA: REFACTOR
• COPY THE SECOND TEST AND RENAME THE COPY
DoItAll_Succeeds_WithMockLogging
• UPDATE THE ASSERT:...
DEPENDENCY KATA: WHAT’S NEXT?
• THERE ARE STILL PLENTY OF THING ABOUT THIS LEGACY CODE I WOULD CHANGE
• WHAT WOULD YOU DO ...
THANKS TO OUR SPONSORS!
To connect to wireless
1. Choose Uguest in the wireless list
2. Open a browser. This will open a U...
Legacy Dependency Killer - Utah Code Camp 2014
Legacy Dependency Killer - Utah Code Camp 2014
Upcoming SlideShare
Loading in …5
×

Legacy Dependency Killer - Utah Code Camp 2014

782
-1

Published on

Legacy Dependency Killer is a hand-on coding session I lead at Utah Code Camp in March 2014. The focus is on refactoring for unit testing. The seed code is available on Github in C# and there are plans to provide translations in other languages. https://github.com/KatasForLegacyCode

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
782
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
1
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Legacy Dependency Killer - Utah Code Camp 2014

  1. 1. SESSION DETAILS • 10-15 MINUTES OF BACKGROUND • 50-55 MINUTES OF HANDS-ON CODING
  2. 2. SESSION DETAILS: YOU NEED THIS STUFF • SEED CODE IS WRITTEN IN C# • GET IT FROM GITHUB: https://github.com/KatasForLegacy Code/kCSharp/archive/Step0.zip • OR FROM ONE OF THE FLASH DRIVES: kCSharp-Step0.zip • ANY VERSION OF VISUAL STUDIO 2012/2013 THAT CAN RUN CONSOLE APPS AND UNIT TESTS • AN NUNIT TEST RUNNER OR THE ABILITY TO QUICKLY SWITCH OUT NUNIT REFERENCE FOR MSTEST. I RECOMMEND NCRUNCH. • WHEN WE ARE DONE CODING, I’M HOPING WE WILL HAVE 5-10 MINUTES FOR Q&A • THE FIRST 5 SUGGESTIONS FOR ADDITIONS OR IMPROVEMENTS TO THIS SESSION/CODE WILL WIN THE FLASH DRIVES
  3. 3. LEGACY EXPECTATION REALITY
  4. 4. LEGACY PERCEPTION - COBOL
  5. 5. LEGACY PERCEPTION - COBOL REALITY – CODE W/O UNIT TESTS
  6. 6. DEPENDENCY EXPECTATION REALITY
  7. 7. DEPENDENCY – THE HORRID TRUTH
  8. 8. KILLER EXPECTATION
  9. 9. “ ” I’VE COMPLETELY SLAUGHTERED ALL THE LEGACY DEPENDENCIES IN OUR CODEBASE. NOW I’LL ENJOY SOME LUNCH.
  10. 10. KILLER EXPECTATION REALITY
  11. 11. PUT IT ALL TOGETHER & WHADDAYA GET •A CODE KATA • A CODE KATA IS AN EXERCISE IN PROGRAMMING WHICH HELPS A PROGRAMMER HONE THEIR SKILLS THROUGH PRACTICE AND REPETITION • THE WORD KATA IS TAKEN FROM JAPANESE ARTS MOST TRADITIONALLY MARTIAL ARTS • WHY? BECAUSE HUMANS LEARN BY DOING
  12. 12. DEPENDENCY KATA • DEPENDENCY KATA: CODE CAMP EDITION • WRITTEN IN C# • NOW WITH LESS TOOL DEPENDENCIES AND RESTRUCTURED TO WORK WITHOUT THEM • ORIGINAL SOURCE CODE AVAILABLE ON GITHUB AT HTTPS://GITHUB.COM/DUBMUN/DEPENDENCYKATA
  13. 13. DEPENDENCY KATA: INITIAL STRUCTURE
  14. 14. DEPENDENCY KATA: FIRST THINGS FIRST • LET’S START BY GETTING THE EXISTING TEST RUNNING • RUNNING THE INTEGRATION TEST SHOWS THAT IT HANGS • WE NEED TO BEGIN BY ABSTRACTING AND BREAKING THE DEPENDENCY ON Console.Readline() • CREATE AN INTERFACE FIRST public interface IConsoleAdapter { string GetInput(); } • CREATE A CLASS THAT IMPLEMENTS THE INTERFACE public class ConsoleAdapter : IConsoleAdapter
  15. 15. DEPENDENCY KATA: FIRST THINGS FIRST • IMPLEMENT METHOD TO HANDLE THE DEPENDENCY public class ConsoleAdapter : IConsoleAdapter { public string GetInput() { return Console.ReadLine(); } } • CREATE NEW CONSTRUCTOR FOR DOITALL THAT ACCEPTS ICONSOLEADAPTER AND SET A PRIVATE VARIABLE private IConsoleAdapter _consoleAdapter; public doItAll(IConsoleAdapter consoleAdapter) { _consoleAdapter = consoleAdapter; } • THEN REPLACE 6 CALLS TO Console.ReadLine() WITH _consoleAdapter.GetInput()
  16. 16. DEPENDENCY KATA: FIRST THINGS FIRST • NOW WE HAVE SOME BROKEN INSTANTIATIONS • IN THE CONSOLE APP INSTANTIATE AND PASS IN OUR NEW HANDLER var doItAll = new DoItAll( new ConsoleAdapter()); • IN THE INTEGRATION TEST WE NEED TO DO SOMETHING DIFFERENT OR OUR TEST WILL STILL FAIL. • CREATE A NEW IMPLEMENTATION OF IConsoleAdaper public class FakeConsoleAdapter : IConsoleAdapter { public string GetInput() { return string.Empty; } }
  17. 17. DEPENDENCY KATA: FIRST THINGS FIRST • WHEN THE TEST IS RUN WE NOW GET A MEANINGFUL EXCEPTION. ALL OF THE DEPENDENCIES THAT CAUSED THE HANG ARE GONE. • THE TEST IS NOW FAILING BECAUSE THE PASSWORD IS EMPTY. THIS IS A MEANINGFUL CASE BUT LET’S JUST UPDATE OUR FAKE FOR NOW. return “fakeInput”; • THE TEST SHOULD BE GREEN NOW!
  18. 18. DEPENDENCY KATA: FIRST THINGS FIRST • WHEN THE TEST IS RUN WE NOW GET A MEANINGFUL EXCEPTION. ALL OF THE DEPENDENCIES THAT CAUSED THE HANG ARE GONE. • THE TEST IS NOW FAILING BECAUSE THE PASSWORD IS EMPTY. THIS IS A MEANINGFUL CASE BUT LET’S JUST UPDATE OUR FAKE FOR NOW. return “fakeInput”; • THE TEST SHOULD BE GREEN NOW! • LET’S ADD AN ASSERT FOR GOOD MEASURE [Test, Category("Integration")] public void DoItAll_Does_ItAll() { var doItAll = new DoItAll(new FakeConsoleAdapter()); Assert.DoesNotThrow(() => doItAll.Do()); }
  19. 19. DEPENDENCY KATA: BETTER COVERAGE • WE DON'T HAVE COVERAGE SOME OF THE CODE STILL AND NO QUANTIFIABLE RESULTS TO TEST • LET’S COPY OUR EXISTING TEST AND RENAME IT DoItAll_Fails_ToWriteToDB • THEN CHANGE THE ASSERT StringAssert.Contains( "Database.SaveToLog Exception:", doItAll.Do()); • THIS WILL FAIL TO BUILD BECAUSE OUR METHOD IS CURRENTLY VOID. LET’S CHANGE THAT • CHANGE DO()’S RETURN TYPE TO STRING • ADD A RETURN STATEMENT IN 2 LOCATIONS: • AT THE END OF THE USING STATEMENT • AT THE END OF THE METHOD • NOW CREATE VARIABLES TO HOLD THE MESSAGES AT VARIOUS POINTS FOR RETURN private const string _passwordsDontMatch = "The passwords don't match.";
  20. 20. DEPENDENCY KATA: BETTER COVERAGE • NOW CREATE VARIABLES TO HOLD THE MESSAGES AT VARIOUS POINTS FOR RETURN private const string _passwordsDontMatch = "The passwords don't match."; AND var errorMessage = string.Format( "{0} - Database.SaveToLog Exception: rn{1}", message, ex.Message); • RETURN THOSE VALUES AS APPROPRIATE • OUR NEW TEST SHOULD NOW PASS
  21. 21. DEPENDENCY KATA: BETTER ABSTRACTION • DO WORK TO ABSTRACT CONSOLE COMPLETELY COMPLETELY • ADD A NEW METHOD STUB TO IConsoleAdapter: Void SetOutput(string output); • UPDATE ConsoleAdapter IMPLEMENTATION public void SetOutput(string output) { Console.WriteLine(output); } • UPDATE FakeConsoleAdapter IMPLEMENTATION public void SetOutput(string output) {} • UPDATE DoItAll IMPLEMENTATION REPLACING 6 INSTANCES OF Console.WriteLine WITH _consoleAdapter.SetOutput • OUR TESTS SHOULD STILL PASS
  22. 22. DEPENDENCY KATA: REFACTOR • DoItAll.Do() IS TRYING TO DO TOO MUCH • EXTRACT LOGGING FUNCTIONALITY BY CREATING A NEW INTERFACE public interface ILogger { string LogMessage(string message); } • NOW EXTRACT THE CODE IN THE TRY/CATCH BLOCK IN DoItAll.Do() INTO THE IMPLEMENTATION OF ILogger.LogMessage() • MAKE SURE ALL PATHS RETURN A MESSAGE • NOW UPDATE THE CONSTRUCTOR OF DoItAll WITH AN ILogger SAND REPLACE TRY/CATCH: message = _logger.LogMessage(message);
  23. 23. DEPENDENCY KATA: REFACTOR • CLIENT NO LONGER BUILDS BECAUSE OF THE UPDATED CONSTRUCTOR SO UPDATE IT • NOW CREATE A NEW FAKE FOR TESTING: public class FakeLogger : ILogger { public string LogMessage( string message) { return string.Empty; } } • UPDATE THE DoItAll MINSTANTIATIONS IN THE TESTS TO INCLUDE new FakeLogger() • THE FIRST TEST PASSES BUT THE OTHER FAILS BECAUSE IT DEPENDS ON IMPLEMENTATION- SPECIFIC DETAILS
  24. 24. DEPENDENCY KATA: REFACTOR • COPY THE SECOND TEST AND RENAME THE COPY DoItAll_Succeeds_WithMockLogging • UPDATE THE ASSERT: Assert.AreEqual( string.Empty, doItAll.Do()); • TEST WILL PASS • LET THE FORMER TEST DEPEND ON DatabaseLogger AND IT WILL PASS AS WELL
  25. 25. DEPENDENCY KATA: WHAT’S NEXT? • THERE ARE STILL PLENTY OF THING ABOUT THIS LEGACY CODE I WOULD CHANGE • WHAT WOULD YOU DO NEXT?
  26. 26. THANKS TO OUR SPONSORS! To connect to wireless 1. Choose Uguest in the wireless list 2. Open a browser. This will open a Uof U website 3. Choose Login
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×