SlideShare a Scribd company logo
1 of 22
Download to read offline
Legacy Code
Quit Complaining, Start Fixing

Saturday, February 15, 14
What Is Legacy Code?

Saturday, February 15, 14
34.                                         }
35.  
36.                                 } else if (!data.getIsOffshore()) { // local
37.  
38.                                         cash = data.getCashBalance();
39.  
40.                                         investment = data.getInvestmentBalance();
41.  

What Is Legacy Code?

42.                                 }
43.  

44.                                 if (<hidden>.getmCurrentExchangeRate().getRate().compareTo(newBigDecimal("0.0000")) == 1) {
45.                                         // convert to current rate
46.                                         cash = cash.divide(<hidden>.getmCurrentExchangeRate().getRate(),BigDecimal.ROUND_UP);
47.                                         investment =investment.divide(<hidden>.getmCurrentExchangeRate().getRate(),
BigDecimal.ROUND_UP);
48.                                 }
49.  
50.                                 // investment slice
51.                                 item = new PieChartItem();
52.                                 item.mLabel = res.getString(R.string.pcs_investment);
53.                                 item.mSliceValue = investment;
54.                                 item.mValue = investment.floatValue();
55.                                 item.mColor = res.getColor(R.color.pcs_teal);
56.                                 slices.add(item);
57.  
58.                                 // cash slice
59.                                 item = new PieChartItem();
60.                                 item.mLabel = res.getString(R.string.pcs_cash);
61.                                 item.mSliceValue = cash;
62.                                 item.mValue = cash.floatValue();
63.                                 item.mColor = res.getColor(R.color.pcs_biscuit);
64.                                 slices.add(item);
65.  
66.                                 mPieChartList.add(slices);
67.                         }
68.  
69.                 }
70.  
Saturday, February 15, 14
What Is Legacy Code?

Code where the tests are an impediment,
not a benefit

Saturday, February 15, 14
Steps
Vent
But get it out of your system
Get it in a Harness
Verify the code around your new code
Add your Code

Saturday, February 15, 14
Seams
A place where you can change existing
behavior without editing code
Objects, Linker, Preprocessor
Enabling Point

Saturday, February 15, 14
var ParseRecurrenceDate = function (recurrencedata) {
var StartTime = DTSTART.exec(recurrencedata)[1];
var EndTime = DTEND.exec(recurrencedata)[1];
if (StartTime.indexOf("T") > 0) {
...
}
var EndDate = RRULE.exec(recurrencedata)[1];
EndDate = new Date(parseInt(EndDate.substr(0, 4), 10),
parseInt(EndDate.substr(4, 2), 10) - 1, parseInt(EndDate.substr(6, 2
10));

Saturday, February 15, 14
     (will-mount [_]

        (let [{:keys [id-key filter tag-fn]} opts
              kill-chan (om/get-state owner :kill-chan)
              tx-chan (om/get-shared owner :tx-chan)
              txs (chan)]
          (assert (not (nil? tx-chan))
            "om-sync requires shared :tx-chan pub channel with :txs topic")
          (async/sub tx-chan :txs txs)
          (om/set-state! owner :txs txs)
          (go (loop []
                (let [dpath (om/path coll)
                      [{:keys [path new-value new-state] :as tx-data} _] (<! txs)
                      ppath (popn (- (count path) (inc (count dpath))) path)]
                  (when (and (subpath? dpath path)
                             (or (nil? filter) (filter tx-data)))
                    (let [tag (if-not (nil? tag-fn)

Saturday, February 15, 14
e void paintBackgroundDisabledAndWindowMaximized(Graphics2D g) {
    roundRect = decodeRoundRect1();
    g.setPaint(decodeGradient1(roundRect));
    g.fill(roundRect);
    roundRect = decodeRoundRect2();
    g.setPaint(decodeGradient2(roundRect));
    g.fill(roundRect);
    rect = decodeRect1();
    g.setPaint(color4);
    g.fill(rect);
    rect = decodeRect2();
    g.setPaint(color5);
    g.fill(rect);
    rect = decodeRect3();

Saturday, February 15, 14
Adapt Parameter
Create New Interface That you can fake
Wrap Hard to instantiate class
Move to interfaces that communicate
responsibilities not implementation - to
avoid over-mocking

Saturday, February 15, 14
e void paintBackgroundDisabledAndWindowMaximized(GraphicsAdapter g) {
    roundRect = decodeRoundRect1();
    g.setPaint(decodeGradient1(roundRect));
    g.fill(roundRect);
    roundRect = decodeRoundRect2();
    g.setPaint(decodeGradient2(roundRect));
    g.fill(roundRect);
    rect = decodeRect1();
    g.setPaint(color4);
    g.fill(rect);
    rect = decodeRect2();
    g.setPaint(color5);
    g.fill(rect);
    rect = decodeRect3();

Saturday, February 15, 14
public class StubGraphicsAdapter implements GraphicsAdapter {
 
public void setPaint(java.awt.Color color) {
}
...
}
 
public class JavaAwtGraphicsAdapter implements GraphicsAdapter {
private Graphics2D g;
public JavaAwtGraphicsAdapter(Graphics2D g) {
this.g = g;
}
public void setPaint(java.awt.Color color) {
this.g.setPaint(color);
}

Saturday, February 15, 14
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Signup Unsuccessful"
message:reason
delegate:NULL
cancelButtonTitle:@"OK"
otherButtonTitles:NULL];

Saturday, February 15, 14
Extract and Override
Identify the call you want to extract
Create a new method on the current class
Override in test

Saturday, February 15, 14
UIAlertView *alert =[[[[self class] alertViewClass] alloc] initWithTitle:@"Signup
message:reason
delegate:NULL
cancelButtonTitle:@"OK"
otherButtonTitles:NULL];

Saturday, February 15, 14
+(Class) alertViewClass
{
return [UIAlertView class];
}
 
// In test file
@interface LoginViewControllerWithTestAlert : LoginViewController
@end
 
@implementation LoginViewControllerWithTestAlert
 
+(Class) alertViewClass
{
return [TestAlert class];
}
 
@end

Saturday, February 15, 14
Static Setter
Allow Subclassing a Singleton
Add a Static Setter
Add a Clear or Reset to avoid Test
Pollution

Saturday, February 15, 14
void MessageRouter::route(Message *message) {
Dispatcher *dispatcher =
ExternalRouter::instance()->getDispatcher();
if (dispatcher != NULL)
dispatcher->sendMessage(message;
}

Saturday, February 15, 14
class ExternalRouter
{
private:
static ExternalRouter *_instance;

ExternalRouter();
public:
static ExternalRouter *instance();
}
 
ExternalRouter *ExternalRouter::_instance = 0;
 
ExternalRouter *ExternalRouter::instance()
{
if (_instance == 0) {
_instance = new ExternalRouter();
}
return _instance;
}

Saturday, February 15, 14
class ExternalRouter
{
private:
static ExternalRouter *_instance;
protected:
ExternalRouter();
public:
static ExternalRouter *instance();
static void setTestingInstance(ExternalRouter *newInstance);
}
 
void ExternalRouter::setTestingInstance(ExternalRouter *newInstance)
{
delete _instance;
_instance = newInstance;
}
 
class TestingExternalRouter : public ExternalRouter
{
public:
virtual void Dispatcher *getDispatcher() const {
return new FakeDispatcher();
}
}

Saturday, February 15, 14
Higher Level Tests

Characterization Tests
In case of emergency break glass.

Saturday, February 15, 14
Resources
Working Effectively With Legacy Code
- Michael Feathers
http://www.reddit.com/r/badcode
@paytonrules (that’s me)
Bullets suck

Saturday, February 15, 14

More Related Content

What's hot

Oops practical file
Oops practical fileOops practical file
Oops practical fileAnkit Dixit
 
Hypercritical C++ Code Review
Hypercritical C++ Code ReviewHypercritical C++ Code Review
Hypercritical C++ Code ReviewAndrey Karpov
 
The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181Mahmoud Samir Fayed
 
Sorting algos > Data Structures & Algorithums
Sorting algos  > Data Structures & AlgorithumsSorting algos  > Data Structures & Algorithums
Sorting algos > Data Structures & AlgorithumsAin-ul-Moiz Khawaja
 
The Ring programming language version 1.9 book - Part 94 of 210
The Ring programming language version 1.9 book - Part 94 of 210The Ring programming language version 1.9 book - Part 94 of 210
The Ring programming language version 1.9 book - Part 94 of 210Mahmoud Samir Fayed
 
Programming with GUTs
Programming with GUTsProgramming with GUTs
Programming with GUTsKevlin Henney
 
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...Istanbul Tech Talks
 
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDKEric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDKGuardSquare
 
The Ring programming language version 1.4 book - Part 21 of 30
The Ring programming language version 1.4 book - Part 21 of 30The Ring programming language version 1.4 book - Part 21 of 30
The Ring programming language version 1.4 book - Part 21 of 30Mahmoud Samir Fayed
 
Formal Verification of Transactional Interaction Contract
Formal Verification of Transactional Interaction ContractFormal Verification of Transactional Interaction Contract
Formal Verification of Transactional Interaction ContractGera Shegalov
 
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6FrontDays
 
Eric Lafortune - ProGuard and DexGuard for optimization and protection
Eric Lafortune - ProGuard and DexGuard for optimization and protectionEric Lafortune - ProGuard and DexGuard for optimization and protection
Eric Lafortune - ProGuard and DexGuard for optimization and protectionGuardSquare
 
BANK MANAGEMENT INVESTIGATORY PROJECT CLASS 12TH
BANK MANAGEMENT INVESTIGATORY PROJECT CLASS 12THBANK MANAGEMENT INVESTIGATORY PROJECT CLASS 12TH
BANK MANAGEMENT INVESTIGATORY PROJECT CLASS 12THSHAJUS5
 
The redux saga begins
The redux saga beginsThe redux saga begins
The redux saga beginsDaniel Franz
 
Aaron Bedra - Effective Software Security Teams
Aaron Bedra - Effective Software Security TeamsAaron Bedra - Effective Software Security Teams
Aaron Bedra - Effective Software Security Teamscentralohioissa
 
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)Games, AI, and Research - Part 2 Training (FightingICE AI Programming)
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)Pujana Paliyawan
 

What's hot (20)

Oops practical file
Oops practical fileOops practical file
Oops practical file
 
Hypercritical C++ Code Review
Hypercritical C++ Code ReviewHypercritical C++ Code Review
Hypercritical C++ Code Review
 
Ip project
Ip projectIp project
Ip project
 
The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181
 
Sorting algos > Data Structures & Algorithums
Sorting algos  > Data Structures & AlgorithumsSorting algos  > Data Structures & Algorithums
Sorting algos > Data Structures & Algorithums
 
The Ring programming language version 1.9 book - Part 94 of 210
The Ring programming language version 1.9 book - Part 94 of 210The Ring programming language version 1.9 book - Part 94 of 210
The Ring programming language version 1.9 book - Part 94 of 210
 
Programming with GUTs
Programming with GUTsProgramming with GUTs
Programming with GUTs
 
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...
 
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDKEric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
 
Ip project visual mobile
Ip project visual mobileIp project visual mobile
Ip project visual mobile
 
Polymorphism
PolymorphismPolymorphism
Polymorphism
 
The Ring programming language version 1.4 book - Part 21 of 30
The Ring programming language version 1.4 book - Part 21 of 30The Ring programming language version 1.4 book - Part 21 of 30
The Ring programming language version 1.4 book - Part 21 of 30
 
C++ practical
C++ practicalC++ practical
C++ practical
 
Formal Verification of Transactional Interaction Contract
Formal Verification of Transactional Interaction ContractFormal Verification of Transactional Interaction Contract
Formal Verification of Transactional Interaction Contract
 
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
 
Eric Lafortune - ProGuard and DexGuard for optimization and protection
Eric Lafortune - ProGuard and DexGuard for optimization and protectionEric Lafortune - ProGuard and DexGuard for optimization and protection
Eric Lafortune - ProGuard and DexGuard for optimization and protection
 
BANK MANAGEMENT INVESTIGATORY PROJECT CLASS 12TH
BANK MANAGEMENT INVESTIGATORY PROJECT CLASS 12THBANK MANAGEMENT INVESTIGATORY PROJECT CLASS 12TH
BANK MANAGEMENT INVESTIGATORY PROJECT CLASS 12TH
 
The redux saga begins
The redux saga beginsThe redux saga begins
The redux saga begins
 
Aaron Bedra - Effective Software Security Teams
Aaron Bedra - Effective Software Security TeamsAaron Bedra - Effective Software Security Teams
Aaron Bedra - Effective Software Security Teams
 
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)Games, AI, and Research - Part 2 Training (FightingICE AI Programming)
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)
 

Similar to Legacy codesmalltalk

Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy codeShriKant Vashishtha
 
All I know about rsc.io/c2go
All I know about rsc.io/c2goAll I know about rsc.io/c2go
All I know about rsc.io/c2goMoriyoshi Koizumi
 
How to transfer bad PLSQL into good (AAAPEKS23)
How to transfer bad PLSQL into good (AAAPEKS23)How to transfer bad PLSQL into good (AAAPEKS23)
How to transfer bad PLSQL into good (AAAPEKS23)Maik Becker
 
in this assignment you are asked to write a simple driver program an.pdf
in this assignment you are asked to write a simple driver program an.pdfin this assignment you are asked to write a simple driver program an.pdf
in this assignment you are asked to write a simple driver program an.pdfmichardsonkhaicarr37
 
Thoughts On Learning A New Programming Language
Thoughts On Learning A New Programming LanguageThoughts On Learning A New Programming Language
Thoughts On Learning A New Programming LanguagePatricia Aas
 
20.1 Java working with abstraction
20.1 Java working with abstraction20.1 Java working with abstraction
20.1 Java working with abstractionIntro C# Book
 
package chapter15;import javafx.application.Application;import j.pdf
package chapter15;import javafx.application.Application;import j.pdfpackage chapter15;import javafx.application.Application;import j.pdf
package chapter15;import javafx.application.Application;import j.pdfKARTIKINDIA
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Nikita Popov
 
생산적인 개발을 위한 지속적인 테스트
생산적인 개발을 위한 지속적인 테스트생산적인 개발을 위한 지속적인 테스트
생산적인 개발을 위한 지속적인 테스트기룡 남
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerAndrey Karpov
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4Abed Bukhari
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJSKyung Yeol Kim
 

Similar to Legacy codesmalltalk (20)

Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
 
All I know about rsc.io/c2go
All I know about rsc.io/c2goAll I know about rsc.io/c2go
All I know about rsc.io/c2go
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
How to transfer bad PLSQL into good (AAAPEKS23)
How to transfer bad PLSQL into good (AAAPEKS23)How to transfer bad PLSQL into good (AAAPEKS23)
How to transfer bad PLSQL into good (AAAPEKS23)
 
in this assignment you are asked to write a simple driver program an.pdf
in this assignment you are asked to write a simple driver program an.pdfin this assignment you are asked to write a simple driver program an.pdf
in this assignment you are asked to write a simple driver program an.pdf
 
Thoughts On Learning A New Programming Language
Thoughts On Learning A New Programming LanguageThoughts On Learning A New Programming Language
Thoughts On Learning A New Programming Language
 
20.1 Java working with abstraction
20.1 Java working with abstraction20.1 Java working with abstraction
20.1 Java working with abstraction
 
package chapter15;import javafx.application.Application;import j.pdf
package chapter15;import javafx.application.Application;import j.pdfpackage chapter15;import javafx.application.Application;import j.pdf
package chapter15;import javafx.application.Application;import j.pdf
 
J slider
J sliderJ slider
J slider
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)
 
생산적인 개발을 위한 지속적인 테스트
생산적인 개발을 위한 지속적인 테스트생산적인 개발을 위한 지속적인 테스트
생산적인 개발을 위한 지속적인 테스트
 
Writing Good Tests
Writing Good TestsWriting Good Tests
Writing Good Tests
 
Fact, Fiction, and FP
Fact, Fiction, and FPFact, Fiction, and FP
Fact, Fiction, and FP
 
Ricky Bobby's World
Ricky Bobby's WorldRicky Bobby's World
Ricky Bobby's World
 
Message in a bottle
Message in a bottleMessage in a bottle
Message in a bottle
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJS
 
#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 

More from Eric Smith

Web Security 100
Web Security 100Web Security 100
Web Security 100Eric Smith
 
Test Driven Cocos2d
Test Driven Cocos2dTest Driven Cocos2d
Test Driven Cocos2dEric Smith
 
Test driven game development silly, stupid or inspired?
Test driven game development   silly, stupid or inspired?Test driven game development   silly, stupid or inspired?
Test driven game development silly, stupid or inspired?Eric Smith
 
Html5 episode 2
Html5 episode 2Html5 episode 2
Html5 episode 2Eric Smith
 
SCMC HTML5 Game Development
SCMC HTML5 Game DevelopmentSCMC HTML5 Game Development
SCMC HTML5 Game DevelopmentEric Smith
 

More from Eric Smith (8)

Web Security 100
Web Security 100Web Security 100
Web Security 100
 
Test Driven Cocos2d
Test Driven Cocos2dTest Driven Cocos2d
Test Driven Cocos2d
 
Test driven game development silly, stupid or inspired?
Test driven game development   silly, stupid or inspired?Test driven game development   silly, stupid or inspired?
Test driven game development silly, stupid or inspired?
 
Tdd in unity
Tdd in unityTdd in unity
Tdd in unity
 
Html5 episode 2
Html5 episode 2Html5 episode 2
Html5 episode 2
 
SCMC HTML5 Game Development
SCMC HTML5 Game DevelopmentSCMC HTML5 Game Development
SCMC HTML5 Game Development
 
8thlightu3
8thlightu38thlightu3
8thlightu3
 
8thlightu2
8thlightu28thlightu2
8thlightu2
 

Legacy codesmalltalk

  • 1. Legacy Code Quit Complaining, Start Fixing Saturday, February 15, 14
  • 2. What Is Legacy Code? Saturday, February 15, 14
  • 3. 34.                                         } 35.   36.                                 } else if (!data.getIsOffshore()) { // local 37.   38.                                         cash = data.getCashBalance(); 39.   40.                                         investment = data.getInvestmentBalance(); 41.   What Is Legacy Code? 42.                                 } 43.   44.                                 if (<hidden>.getmCurrentExchangeRate().getRate().compareTo(newBigDecimal("0.0000")) == 1) { 45.                                         // convert to current rate 46.                                         cash = cash.divide(<hidden>.getmCurrentExchangeRate().getRate(),BigDecimal.ROUND_UP); 47.                                         investment =investment.divide(<hidden>.getmCurrentExchangeRate().getRate(), BigDecimal.ROUND_UP); 48.                                 } 49.   50.                                 // investment slice 51.                                 item = new PieChartItem(); 52.                                 item.mLabel = res.getString(R.string.pcs_investment); 53.                                 item.mSliceValue = investment; 54.                                 item.mValue = investment.floatValue(); 55.                                 item.mColor = res.getColor(R.color.pcs_teal); 56.                                 slices.add(item); 57.   58.                                 // cash slice 59.                                 item = new PieChartItem(); 60.                                 item.mLabel = res.getString(R.string.pcs_cash); 61.                                 item.mSliceValue = cash; 62.                                 item.mValue = cash.floatValue(); 63.                                 item.mColor = res.getColor(R.color.pcs_biscuit); 64.                                 slices.add(item); 65.   66.                                 mPieChartList.add(slices); 67.                         } 68.   69.                 } 70.   Saturday, February 15, 14
  • 4. What Is Legacy Code? Code where the tests are an impediment, not a benefit Saturday, February 15, 14
  • 5. Steps Vent But get it out of your system Get it in a Harness Verify the code around your new code Add your Code Saturday, February 15, 14
  • 6. Seams A place where you can change existing behavior without editing code Objects, Linker, Preprocessor Enabling Point Saturday, February 15, 14
  • 7. var ParseRecurrenceDate = function (recurrencedata) { var StartTime = DTSTART.exec(recurrencedata)[1]; var EndTime = DTEND.exec(recurrencedata)[1]; if (StartTime.indexOf("T") > 0) { ... } var EndDate = RRULE.exec(recurrencedata)[1]; EndDate = new Date(parseInt(EndDate.substr(0, 4), 10), parseInt(EndDate.substr(4, 2), 10) - 1, parseInt(EndDate.substr(6, 2 10)); Saturday, February 15, 14
  • 8.      (will-mount [_]         (let [{:keys [id-key filter tag-fn]} opts               kill-chan (om/get-state owner :kill-chan)               tx-chan (om/get-shared owner :tx-chan)               txs (chan)]           (assert (not (nil? tx-chan))             "om-sync requires shared :tx-chan pub channel with :txs topic")           (async/sub tx-chan :txs txs)           (om/set-state! owner :txs txs)           (go (loop []                 (let [dpath (om/path coll)                       [{:keys [path new-value new-state] :as tx-data} _] (<! txs)                       ppath (popn (- (count path) (inc (count dpath))) path)]                   (when (and (subpath? dpath path)                              (or (nil? filter) (filter tx-data)))                     (let [tag (if-not (nil? tag-fn) Saturday, February 15, 14
  • 9. e void paintBackgroundDisabledAndWindowMaximized(Graphics2D g) {     roundRect = decodeRoundRect1();     g.setPaint(decodeGradient1(roundRect));     g.fill(roundRect);     roundRect = decodeRoundRect2();     g.setPaint(decodeGradient2(roundRect));     g.fill(roundRect);     rect = decodeRect1();     g.setPaint(color4);     g.fill(rect);     rect = decodeRect2();     g.setPaint(color5);     g.fill(rect);     rect = decodeRect3(); Saturday, February 15, 14
  • 10. Adapt Parameter Create New Interface That you can fake Wrap Hard to instantiate class Move to interfaces that communicate responsibilities not implementation - to avoid over-mocking Saturday, February 15, 14
  • 11. e void paintBackgroundDisabledAndWindowMaximized(GraphicsAdapter g) {     roundRect = decodeRoundRect1();     g.setPaint(decodeGradient1(roundRect));     g.fill(roundRect);     roundRect = decodeRoundRect2();     g.setPaint(decodeGradient2(roundRect));     g.fill(roundRect);     rect = decodeRect1();     g.setPaint(color4);     g.fill(rect);     rect = decodeRect2();     g.setPaint(color5);     g.fill(rect);     rect = decodeRect3(); Saturday, February 15, 14
  • 12. public class StubGraphicsAdapter implements GraphicsAdapter {   public void setPaint(java.awt.Color color) { } ... }   public class JavaAwtGraphicsAdapter implements GraphicsAdapter { private Graphics2D g; public JavaAwtGraphicsAdapter(Graphics2D g) { this.g = g; } public void setPaint(java.awt.Color color) { this.g.setPaint(color); } Saturday, February 15, 14
  • 13. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Signup Unsuccessful" message:reason delegate:NULL cancelButtonTitle:@"OK" otherButtonTitles:NULL]; Saturday, February 15, 14
  • 14. Extract and Override Identify the call you want to extract Create a new method on the current class Override in test Saturday, February 15, 14
  • 15. UIAlertView *alert =[[[[self class] alertViewClass] alloc] initWithTitle:@"Signup message:reason delegate:NULL cancelButtonTitle:@"OK" otherButtonTitles:NULL]; Saturday, February 15, 14
  • 16. +(Class) alertViewClass { return [UIAlertView class]; }   // In test file @interface LoginViewControllerWithTestAlert : LoginViewController @end   @implementation LoginViewControllerWithTestAlert   +(Class) alertViewClass { return [TestAlert class]; }   @end Saturday, February 15, 14
  • 17. Static Setter Allow Subclassing a Singleton Add a Static Setter Add a Clear or Reset to avoid Test Pollution Saturday, February 15, 14
  • 18. void MessageRouter::route(Message *message) { Dispatcher *dispatcher = ExternalRouter::instance()->getDispatcher(); if (dispatcher != NULL) dispatcher->sendMessage(message; } Saturday, February 15, 14
  • 19. class ExternalRouter { private: static ExternalRouter *_instance; ExternalRouter(); public: static ExternalRouter *instance(); }   ExternalRouter *ExternalRouter::_instance = 0;   ExternalRouter *ExternalRouter::instance() { if (_instance == 0) { _instance = new ExternalRouter(); } return _instance; } Saturday, February 15, 14
  • 20. class ExternalRouter { private: static ExternalRouter *_instance; protected: ExternalRouter(); public: static ExternalRouter *instance(); static void setTestingInstance(ExternalRouter *newInstance); }   void ExternalRouter::setTestingInstance(ExternalRouter *newInstance) { delete _instance; _instance = newInstance; }   class TestingExternalRouter : public ExternalRouter { public: virtual void Dispatcher *getDispatcher() const { return new FakeDispatcher(); } } Saturday, February 15, 14
  • 21. Higher Level Tests Characterization Tests In case of emergency break glass. Saturday, February 15, 14
  • 22. Resources Working Effectively With Legacy Code - Michael Feathers http://www.reddit.com/r/badcode @paytonrules (that’s me) Bullets suck Saturday, February 15, 14