SlideShare a Scribd company logo
1 of 34
Download to read offline
How to Write Unit Test for
New Code on top of Legacy Code


Joseph Yao
Please Read This Great Book!
Unit Test 101
What’s Unit Test?

Unit tests is the idea that they are tests in
isolation of individual components of software


                            - Michael C. Feathers
What’s Legacy Code?
Legacy code is simply code without tests.


Without tests is bad code. It doesn't matter how well written
it is; it doesn't matter how pretty or object-oriented or well-
encapsulated it is. With tests, we can change the behavior
of our code quickly and verifiably. Without them, we really
don't know if our code is getting better or worse.


                                          - Michael C. Feathers
Make New Code Testable
How to Initialize Dependency




               Need



                      Legacy Code
  New Code
Your Code Looks Like This?
public class Car {
      private Engine engine;

      public Car() {
            engine = new Engine();
      }

      public void run() {
            engine.start();
      }

      public String status() {
            return engine.speed() > 0 ? “Move”: “Stop”;
      }
}
Your Test Looks Like This?
public class TestCar {
     @Test public void move() {
            Car car = new Car();
            car.run();
            assertEquals(“Move”, car.status());
     }
}


         Are you really do the unit test for Car?
Code for Car with Isolation
public class Car {
      private IEngine engine;

      public Car(IEngine theEngine) {
            engine = theEngine;
      }

      public void run() {
            engine.start();
      }

      public String status() {
            return engine.speed() > 0 ? “Move”: “Stop”;
      }
}
Test for Car with Isolation
public class TestCar {
      @Test public void move() {
            IEngine engineMock =
                  new EngineMock(10);
            Car car = new Car(engineMock);
            car.run();
            assertEquals(“Move”, car.status());
      }
}


In fact, you don’t care how engine speed is calculated
I Need to Test a Private Method
Your Code Looks Like This?
public class Order {
     public void addItem(Item item) {
           if (isValidItem(item)) {
                items.add(item);
           }
     }
     private boolean isValidItem(Item item) {
           more than 500 lines code…
     }
}


      How can I test the private method?
Does Your Class Have too many Responsibilities?
Maybe This Code is Better?
public class Order {
     private ItemValidator validator;
     public Order (ItemValidator
          theValidator) {
          validator = theValidator;
     }
     public void addItem (Item item) {
          if (validator.
               isValidItem(item)) {
               …
          }
     }
}
Single Responsibility Principle
“Don’t Do it” unless you have a Very Strong Reason




                                   +
Good design is testable, and
design that isn't testable is bad



              - Michael C. Feathers
Isolate Legacy Code
Too hard to get Legacy Code under Test
Some New Code needed to be added
 public class Customer {
      …
      public void purchase() {
               more than 500 lines of legacy code…
        }
        …
 }

 We need to log this customer purchase action after it done.

Can you add unit test for new code with no impact to legacy code?
Add new code by Sprout Method
public class Customer {
     public void purchase() {
           purchaseWithoutLog();
           logPurchaseAction();
     }
     protected void purchaseWithoutLog() {
           more than 500 lines of legacy code…
      }
      private void logPurchaseAction() {
           Your new code here…
      }
}
Your Test May Look Like This
public class TestCustomerPurchaseLog extends
     Customer {
     @Test public void log() {
           Customer customer =
                new TestCustomerPurchaseLog();
           customer.purchase();
           … code to verify the log action …
     }

     protected void purchaseWithoutLog() {}
}
Some other Alternative Ways

• Sprout Method – the Sample Code

• Wrap Method

• If the legacy class is hard to be put into test
  harness
  o Sprout Class

  o Wrap Class

  o This is quite useful when you can’t easily isolate the
    dependency for legacy class
I have a Monster Dependency to Isolate
How to Isolate “HttpServletRequest”?
public class ARMDispatcher {

    public void populate (HttpServletRequest request) {

        String [] values
               = request.getParameterValues(pageStateName);

        if (values != null && values.length   > 0) {

               marketBindings.put(

               pageStateName + getDateStamp(), values[0]);

        }

    }

}
You only Need to get the Parameter Value
public class ARMDispatcher {

    public void populate (ParameterSource source) {

        String value =

        source.getParameterForName(pageStateName);

        if (value != null) {

              marketBindings.put(

              ageStateName + getDateStamp(), value);

        }

    }

}
I need D, but it’s from A.getB().getC().getD()
Your Code may Look like this
public class Customer {
    private Orders orders;
    public List<String> getAllItemNamesOfLatestOrder(){
        List<String> allNames =
              new ArrayList<String>();
        Item[] items =
              orders.getLatestOrder().getAllItems();
        for (Item item : items) {
              allNames.add(item.getName());
        }
        return allNames;
    }
}
You need to Isolate the way to Get Items
public class Customer {
  private Orders orders;
  public List<String> getAllItemNamesOfLatestOrder(){
      List<String> allNames =
            new ArrayList<String>();
      Item[] items = getAllItemsOfLatestOrder();
      for (Item item : items) {
            allNames.add(item.getName());
      }
      return allNames;
  }
  protected Item[] getAllItemsOfLatestOrder() {
      return orders.getLatestOrder().getAllItems();
  }
}
Suggestions
Test Behavior
      instead of

Test Implementation
Dependency Isolation Tool is


         Evil
Q&A




     新浪微博 @姚若舟
      TDD Code Kata
@tudou.com/home/yaoruozhou

More Related Content

What's hot

What's hot (20)

Rechecking SharpDevelop: Any New Bugs?
Rechecking SharpDevelop: Any New Bugs?Rechecking SharpDevelop: Any New Bugs?
Rechecking SharpDevelop: Any New Bugs?
 
Inside PyMongo - MongoNYC
Inside PyMongo - MongoNYCInside PyMongo - MongoNYC
Inside PyMongo - MongoNYC
 
Тарас Олексин - Sculpt! Your! Tests!
Тарас Олексин  - Sculpt! Your! Tests!Тарас Олексин  - Sculpt! Your! Tests!
Тарас Олексин - Sculpt! Your! Tests!
 
Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
 
Secret unit testing tools no one ever told you about
Secret unit testing tools no one ever told you aboutSecret unit testing tools no one ever told you about
Secret unit testing tools no one ever told you about
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicox
 
Policy Injection in ASP.NET using Enterprise Library 3.0
Policy Injection in ASP.NET using Enterprise Library 3.0Policy Injection in ASP.NET using Enterprise Library 3.0
Policy Injection in ASP.NET using Enterprise Library 3.0
 
ERRest
ERRestERRest
ERRest
 
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
 
Graphql, REST and Apollo
Graphql, REST and ApolloGraphql, REST and Apollo
Graphql, REST and Apollo
 
jasmine
jasminejasmine
jasmine
 
Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)
 
Beyond Design Principles and Patterns
Beyond Design Principles and PatternsBeyond Design Principles and Patterns
Beyond Design Principles and Patterns
 
ES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesES3-2020-07 Testing techniques
ES3-2020-07 Testing techniques
 
Unit testing patterns for concurrent code
Unit testing patterns for concurrent codeUnit testing patterns for concurrent code
Unit testing patterns for concurrent code
 
Clean Test Code
Clean Test CodeClean Test Code
Clean Test Code
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctly
 
Developer Test - Things to Know
Developer Test - Things to KnowDeveloper Test - Things to Know
Developer Test - Things to Know
 
ERRest in Depth
ERRest in DepthERRest in Depth
ERRest in Depth
 

Viewers also liked

Theory and practice – migrating your legacy code into our modern test drive...
Theory and practice – migrating your  legacy code into our modern test  drive...Theory and practice – migrating your  legacy code into our modern test  drive...
Theory and practice – migrating your legacy code into our modern test drive...
Lars Jankowfsky
 

Viewers also liked (20)

Working Effectively with Legacy Code
Working Effectively with Legacy CodeWorking Effectively with Legacy Code
Working Effectively with Legacy Code
 
Test Driven Infrastructure na Globo.com
Test Driven Infrastructure na Globo.comTest Driven Infrastructure na Globo.com
Test Driven Infrastructure na Globo.com
 
Adding Unit Test To Legacy Code
Adding Unit Test To Legacy CodeAdding Unit Test To Legacy Code
Adding Unit Test To Legacy Code
 
Getting Unstuck: Working with Legacy Code and Data
Getting Unstuck: Working with Legacy Code and DataGetting Unstuck: Working with Legacy Code and Data
Getting Unstuck: Working with Legacy Code and Data
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Working With Legacy Code
Working With Legacy CodeWorking With Legacy Code
Working With Legacy Code
 
Working with legacy code 3
Working with legacy code 3Working with legacy code 3
Working with legacy code 3
 
TDD depois do mainstream. E agora?
TDD depois do mainstream. E agora?TDD depois do mainstream. E agora?
TDD depois do mainstream. E agora?
 
Theory and practice – migrating your legacy code into our modern test drive...
Theory and practice – migrating your  legacy code into our modern test  drive...Theory and practice – migrating your  legacy code into our modern test  drive...
Theory and practice – migrating your legacy code into our modern test drive...
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
How to Start Test-Driven Development in Legacy Code
How to Start Test-Driven Development in Legacy CodeHow to Start Test-Driven Development in Legacy Code
How to Start Test-Driven Development in Legacy Code
 
Brownfield applications: dicas, técnicas e experiências
Brownfield applications: dicas, técnicas e experiênciasBrownfield applications: dicas, técnicas e experiências
Brownfield applications: dicas, técnicas e experiências
 
Onde nenhum desenvolvedor jamais testou: Introduzindo testes unitários em cód...
Onde nenhum desenvolvedor jamais testou: Introduzindo testes unitários em cód...Onde nenhum desenvolvedor jamais testou: Introduzindo testes unitários em cód...
Onde nenhum desenvolvedor jamais testou: Introduzindo testes unitários em cód...
 
Unit testing legacy code
Unit testing legacy codeUnit testing legacy code
Unit testing legacy code
 
Testing strategies for legacy code
Testing strategies for legacy codeTesting strategies for legacy code
Testing strategies for legacy code
 
Reversed Test Pyramid - Testing and dealing with Legacy Code
Reversed Test Pyramid - Testing and dealing with Legacy CodeReversed Test Pyramid - Testing and dealing with Legacy Code
Reversed Test Pyramid - Testing and dealing with Legacy Code
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
Tactics for Implementing Test Automation for Legacy Code
Tactics for Implementing Test Automation for Legacy CodeTactics for Implementing Test Automation for Legacy Code
Tactics for Implementing Test Automation for Legacy Code
 
Workshop fight legacy code write unit test
Workshop fight legacy code write unit testWorkshop fight legacy code write unit test
Workshop fight legacy code write unit test
 
Modernising Legacy Code
Modernising Legacy CodeModernising Legacy Code
Modernising Legacy Code
 

Similar to Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:how to write unit test for new code based on legacy code(姚若舟)

Keep your Wicket application in production
Keep your Wicket application in productionKeep your Wicket application in production
Keep your Wicket application in production
Martijn Dashorst
 
Refactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartRefactoring In Tdd The Missing Part
Refactoring In Tdd The Missing Part
Gabriele Lana
 

Similar to Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:how to write unit test for new code based on legacy code(姚若舟) (20)

Post Sharp Talk
Post Sharp TalkPost Sharp Talk
Post Sharp Talk
 
Security Testing
Security TestingSecurity Testing
Security Testing
 
Apex Testing and Best Practices
Apex Testing and Best PracticesApex Testing and Best Practices
Apex Testing and Best Practices
 
Clean tests good tests
Clean tests   good testsClean tests   good tests
Clean tests good tests
 
Refactoring and code smells
Refactoring and code smellsRefactoring and code smells
Refactoring and code smells
 
How to write clean tests
How to write clean testsHow to write clean tests
How to write clean tests
 
Testing AngularJS
Testing AngularJSTesting AngularJS
Testing AngularJS
 
Pragmatic unittestingwithj unit
Pragmatic unittestingwithj unitPragmatic unittestingwithj unit
Pragmatic unittestingwithj unit
 
Not your father's tests
Not your father's testsNot your father's tests
Not your father's tests
 
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014
 
Building unit tests correctly with visual studio 2013
Building unit tests correctly with visual studio 2013Building unit tests correctly with visual studio 2013
Building unit tests correctly with visual studio 2013
 
Keep your Wicket application in production
Keep your Wicket application in productionKeep your Wicket application in production
Keep your Wicket application in production
 
JDK Power Tools
JDK Power ToolsJDK Power Tools
JDK Power Tools
 
Android ui layouts ,cntls,webservices examples codes
Android ui layouts ,cntls,webservices examples codesAndroid ui layouts ,cntls,webservices examples codes
Android ui layouts ,cntls,webservices examples codes
 
Refactoring In Tdd The Missing Part
Refactoring In Tdd The Missing PartRefactoring In Tdd The Missing Part
Refactoring In Tdd The Missing Part
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java Developers
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Test Driven Development with JavaFX
Test Driven Development with JavaFXTest Driven Development with JavaFX
Test Driven Development with JavaFX
 
The secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you aboutThe secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you about
 
The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42
 

More from LetAgileFly

Sponsorship program 2013 regional scrum gathering china
Sponsorship program 2013 regional scrum gathering chinaSponsorship program 2013 regional scrum gathering china
Sponsorship program 2013 regional scrum gathering china
LetAgileFly
 
Scrum Gathering 2012 Shanghai_领导力与组织转型:scrum in china the hard way (oliver ...
Scrum Gathering 2012 Shanghai_领导力与组织转型:scrum in china   the hard way (oliver ...Scrum Gathering 2012 Shanghai_领导力与组织转型:scrum in china   the hard way (oliver ...
Scrum Gathering 2012 Shanghai_领导力与组织转型:scrum in china the hard way (oliver ...
LetAgileFly
 
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
LetAgileFly
 
Scrum Gathering 2012 Shanghai_创业创新分会场:设计拥抱敏捷环境的办公室(胡凯)
Scrum Gathering 2012 Shanghai_创业创新分会场:设计拥抱敏捷环境的办公室(胡凯)Scrum Gathering 2012 Shanghai_创业创新分会场:设计拥抱敏捷环境的办公室(胡凯)
Scrum Gathering 2012 Shanghai_创业创新分会场:设计拥抱敏捷环境的办公室(胡凯)
LetAgileFly
 
Scrum gathering 2012 shanghai 播种敏捷分会场演讲话题:敏捷估算的新视角(Alan Atlas)
Scrum gathering 2012 shanghai 播种敏捷分会场演讲话题:敏捷估算的新视角(Alan Atlas)Scrum gathering 2012 shanghai 播种敏捷分会场演讲话题:敏捷估算的新视角(Alan Atlas)
Scrum gathering 2012 shanghai 播种敏捷分会场演讲话题:敏捷估算的新视角(Alan Atlas)
LetAgileFly
 
Scrum Gathering 2012 Shanghai_敏捷测试与质量管理分会场演讲话题:探索性测试之旅 – 我们团队的探索性测试实战经验(张克冰)
Scrum Gathering 2012 Shanghai_敏捷测试与质量管理分会场演讲话题:探索性测试之旅 – 我们团队的探索性测试实战经验(张克冰)Scrum Gathering 2012 Shanghai_敏捷测试与质量管理分会场演讲话题:探索性测试之旅 – 我们团队的探索性测试实战经验(张克冰)
Scrum Gathering 2012 Shanghai_敏捷测试与质量管理分会场演讲话题:探索性测试之旅 – 我们团队的探索性测试实战经验(张克冰)
LetAgileFly
 
Scrum Gathering 2012 Shanghai 精益与持续改进分会场:6年一线敏捷实践心得分享之持续集成(秦之远)
Scrum Gathering 2012 Shanghai 精益与持续改进分会场:6年一线敏捷实践心得分享之持续集成(秦之远)Scrum Gathering 2012 Shanghai 精益与持续改进分会场:6年一线敏捷实践心得分享之持续集成(秦之远)
Scrum Gathering 2012 Shanghai 精益与持续改进分会场:6年一线敏捷实践心得分享之持续集成(秦之远)
LetAgileFly
 
Scrum gathering 2012 shanghai 团队合作与团队指导:scrum master 取经路(王庆付)
Scrum gathering 2012 shanghai 团队合作与团队指导:scrum master 取经路(王庆付)Scrum gathering 2012 shanghai 团队合作与团队指导:scrum master 取经路(王庆付)
Scrum gathering 2012 shanghai 团队合作与团队指导:scrum master 取经路(王庆付)
LetAgileFly
 
Scrum Gathering 2012 Shanghai_Keynote: how to change the world(jurgen appelo)
Scrum Gathering 2012 Shanghai_Keynote: how to change the world(jurgen appelo)Scrum Gathering 2012 Shanghai_Keynote: how to change the world(jurgen appelo)
Scrum Gathering 2012 Shanghai_Keynote: how to change the world(jurgen appelo)
LetAgileFly
 
Scrum gathering 2012 shanghai 团队合作与团队指导分会场演讲话题:你的团队什么颜色的(杨瑞)
Scrum gathering 2012 shanghai  团队合作与团队指导分会场演讲话题:你的团队什么颜色的(杨瑞)Scrum gathering 2012 shanghai  团队合作与团队指导分会场演讲话题:你的团队什么颜色的(杨瑞)
Scrum gathering 2012 shanghai 团队合作与团队指导分会场演讲话题:你的团队什么颜色的(杨瑞)
LetAgileFly
 
Scrum gathering 2012 shanghai 领导力与组织转型分会场演讲话题:让飞行中的敏捷软着陆(李忠利)
Scrum gathering 2012 shanghai  领导力与组织转型分会场演讲话题:让飞行中的敏捷软着陆(李忠利)Scrum gathering 2012 shanghai  领导力与组织转型分会场演讲话题:让飞行中的敏捷软着陆(李忠利)
Scrum gathering 2012 shanghai 领导力与组织转型分会场演讲话题:让飞行中的敏捷软着陆(李忠利)
LetAgileFly
 
Scrum gathering 2012 shanghai 精益与持续改进分会场演讲话题: 大型企业ci平台建设和实施分享(陈小光)
Scrum gathering 2012 shanghai  精益与持续改进分会场演讲话题: 大型企业ci平台建设和实施分享(陈小光)Scrum gathering 2012 shanghai  精益与持续改进分会场演讲话题: 大型企业ci平台建设和实施分享(陈小光)
Scrum gathering 2012 shanghai 精益与持续改进分会场演讲话题: 大型企业ci平台建设和实施分享(陈小光)
LetAgileFly
 
Scrum Gathering 2012 Shanghai 播种敏捷分会场演讲话题:敏捷项目管理在互联网公司中的应用(钱安川)
Scrum Gathering 2012 Shanghai  播种敏捷分会场演讲话题:敏捷项目管理在互联网公司中的应用(钱安川)Scrum Gathering 2012 Shanghai  播种敏捷分会场演讲话题:敏捷项目管理在互联网公司中的应用(钱安川)
Scrum Gathering 2012 Shanghai 播种敏捷分会场演讲话题:敏捷项目管理在互联网公司中的应用(钱安川)
LetAgileFly
 

More from LetAgileFly (20)

Sponsorship program 2013 regional scrum gathering china
Sponsorship program 2013 regional scrum gathering chinaSponsorship program 2013 regional scrum gathering china
Sponsorship program 2013 regional scrum gathering china
 
Scrum gathering 2012 shanghai_敏捷测试与质量管理分会场演讲话题:快速可持续的高质量发布(路宁)
Scrum gathering 2012 shanghai_敏捷测试与质量管理分会场演讲话题:快速可持续的高质量发布(路宁)Scrum gathering 2012 shanghai_敏捷测试与质量管理分会场演讲话题:快速可持续的高质量发布(路宁)
Scrum gathering 2012 shanghai_敏捷测试与质量管理分会场演讲话题:快速可持续的高质量发布(路宁)
 
Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:编程练习(尹哲)
Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:编程练习(尹哲)Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:编程练习(尹哲)
Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:编程练习(尹哲)
 
Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:持续集成–从地面到云端(许晓斌)
Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:持续集成–从地面到云端(许晓斌)Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:持续集成–从地面到云端(许晓斌)
Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:持续集成–从地面到云端(许晓斌)
 
Scrum Gathering 2012 Shanghai_领导力与组织转型:scrum in china the hard way (oliver ...
Scrum Gathering 2012 Shanghai_领导力与组织转型:scrum in china   the hard way (oliver ...Scrum Gathering 2012 Shanghai_领导力与组织转型:scrum in china   the hard way (oliver ...
Scrum Gathering 2012 Shanghai_领导力与组织转型:scrum in china the hard way (oliver ...
 
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
 
Scrum Gathering 2012 Shanghai_创业创新分会场:设计拥抱敏捷环境的办公室(胡凯)
Scrum Gathering 2012 Shanghai_创业创新分会场:设计拥抱敏捷环境的办公室(胡凯)Scrum Gathering 2012 Shanghai_创业创新分会场:设计拥抱敏捷环境的办公室(胡凯)
Scrum Gathering 2012 Shanghai_创业创新分会场:设计拥抱敏捷环境的办公室(胡凯)
 
Scrum gathering 2012 shanghai 播种敏捷分会场演讲话题:敏捷估算的新视角(Alan Atlas)
Scrum gathering 2012 shanghai 播种敏捷分会场演讲话题:敏捷估算的新视角(Alan Atlas)Scrum gathering 2012 shanghai 播种敏捷分会场演讲话题:敏捷估算的新视角(Alan Atlas)
Scrum gathering 2012 shanghai 播种敏捷分会场演讲话题:敏捷估算的新视角(Alan Atlas)
 
Scrum Gathering 2012 Shanghai_敏捷测试与质量管理分会场演讲话题:探索性测试之旅 – 我们团队的探索性测试实战经验(张克冰)
Scrum Gathering 2012 Shanghai_敏捷测试与质量管理分会场演讲话题:探索性测试之旅 – 我们团队的探索性测试实战经验(张克冰)Scrum Gathering 2012 Shanghai_敏捷测试与质量管理分会场演讲话题:探索性测试之旅 – 我们团队的探索性测试实战经验(张克冰)
Scrum Gathering 2012 Shanghai_敏捷测试与质量管理分会场演讲话题:探索性测试之旅 – 我们团队的探索性测试实战经验(张克冰)
 
Scrum Gathering 2012 Shanghai_产品管理及用户体验 分会场:实例化需求的实践(蔡煜)
Scrum Gathering 2012 Shanghai_产品管理及用户体验 分会场:实例化需求的实践(蔡煜)Scrum Gathering 2012 Shanghai_产品管理及用户体验 分会场:实例化需求的实践(蔡煜)
Scrum Gathering 2012 Shanghai_产品管理及用户体验 分会场:实例化需求的实践(蔡煜)
 
Scrum Gathering 2012 Shanghai_领导力与组织转型:企业敏捷转型所面临的文化挑战
Scrum Gathering 2012 Shanghai_领导力与组织转型:企业敏捷转型所面临的文化挑战Scrum Gathering 2012 Shanghai_领导力与组织转型:企业敏捷转型所面临的文化挑战
Scrum Gathering 2012 Shanghai_领导力与组织转型:企业敏捷转型所面临的文化挑战
 
Scrum Gathering 2012 Shanghai_敏捷测试与质量管理分会场演讲话题:getting to done by testing at ...
Scrum Gathering 2012 Shanghai_敏捷测试与质量管理分会场演讲话题:getting to done by testing at ...Scrum Gathering 2012 Shanghai_敏捷测试与质量管理分会场演讲话题:getting to done by testing at ...
Scrum Gathering 2012 Shanghai_敏捷测试与质量管理分会场演讲话题:getting to done by testing at ...
 
Scrum Gathering 2012 Shanghai 精益与持续改进分会场:6年一线敏捷实践心得分享之持续集成(秦之远)
Scrum Gathering 2012 Shanghai 精益与持续改进分会场:6年一线敏捷实践心得分享之持续集成(秦之远)Scrum Gathering 2012 Shanghai 精益与持续改进分会场:6年一线敏捷实践心得分享之持续集成(秦之远)
Scrum Gathering 2012 Shanghai 精益与持续改进分会场:6年一线敏捷实践心得分享之持续集成(秦之远)
 
Scrum Gathering 2012 Shanghai_产品管理及用户体验 分会场:如何提高与业务客户沟通质量(侯伯薇)
Scrum Gathering 2012 Shanghai_产品管理及用户体验 分会场:如何提高与业务客户沟通质量(侯伯薇)Scrum Gathering 2012 Shanghai_产品管理及用户体验 分会场:如何提高与业务客户沟通质量(侯伯薇)
Scrum Gathering 2012 Shanghai_产品管理及用户体验 分会场:如何提高与业务客户沟通质量(侯伯薇)
 
Scrum gathering 2012 shanghai 团队合作与团队指导:scrum master 取经路(王庆付)
Scrum gathering 2012 shanghai 团队合作与团队指导:scrum master 取经路(王庆付)Scrum gathering 2012 shanghai 团队合作与团队指导:scrum master 取经路(王庆付)
Scrum gathering 2012 shanghai 团队合作与团队指导:scrum master 取经路(王庆付)
 
Scrum Gathering 2012 Shanghai_Keynote: how to change the world(jurgen appelo)
Scrum Gathering 2012 Shanghai_Keynote: how to change the world(jurgen appelo)Scrum Gathering 2012 Shanghai_Keynote: how to change the world(jurgen appelo)
Scrum Gathering 2012 Shanghai_Keynote: how to change the world(jurgen appelo)
 
Scrum gathering 2012 shanghai 团队合作与团队指导分会场演讲话题:你的团队什么颜色的(杨瑞)
Scrum gathering 2012 shanghai  团队合作与团队指导分会场演讲话题:你的团队什么颜色的(杨瑞)Scrum gathering 2012 shanghai  团队合作与团队指导分会场演讲话题:你的团队什么颜色的(杨瑞)
Scrum gathering 2012 shanghai 团队合作与团队指导分会场演讲话题:你的团队什么颜色的(杨瑞)
 
Scrum gathering 2012 shanghai 领导力与组织转型分会场演讲话题:让飞行中的敏捷软着陆(李忠利)
Scrum gathering 2012 shanghai  领导力与组织转型分会场演讲话题:让飞行中的敏捷软着陆(李忠利)Scrum gathering 2012 shanghai  领导力与组织转型分会场演讲话题:让飞行中的敏捷软着陆(李忠利)
Scrum gathering 2012 shanghai 领导力与组织转型分会场演讲话题:让飞行中的敏捷软着陆(李忠利)
 
Scrum gathering 2012 shanghai 精益与持续改进分会场演讲话题: 大型企业ci平台建设和实施分享(陈小光)
Scrum gathering 2012 shanghai  精益与持续改进分会场演讲话题: 大型企业ci平台建设和实施分享(陈小光)Scrum gathering 2012 shanghai  精益与持续改进分会场演讲话题: 大型企业ci平台建设和实施分享(陈小光)
Scrum gathering 2012 shanghai 精益与持续改进分会场演讲话题: 大型企业ci平台建设和实施分享(陈小光)
 
Scrum Gathering 2012 Shanghai 播种敏捷分会场演讲话题:敏捷项目管理在互联网公司中的应用(钱安川)
Scrum Gathering 2012 Shanghai  播种敏捷分会场演讲话题:敏捷项目管理在互联网公司中的应用(钱安川)Scrum Gathering 2012 Shanghai  播种敏捷分会场演讲话题:敏捷项目管理在互联网公司中的应用(钱安川)
Scrum Gathering 2012 Shanghai 播种敏捷分会场演讲话题:敏捷项目管理在互联网公司中的应用(钱安川)
 

Recently uploaded

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 

Scrum Gathering 2012 Shanghai_工程实践与技术卓越分会场:how to write unit test for new code based on legacy code(姚若舟)

  • 1. How to Write Unit Test for New Code on top of Legacy Code Joseph Yao
  • 2. Please Read This Great Book!
  • 4. What’s Unit Test? Unit tests is the idea that they are tests in isolation of individual components of software - Michael C. Feathers
  • 5. What’s Legacy Code? Legacy code is simply code without tests. Without tests is bad code. It doesn't matter how well written it is; it doesn't matter how pretty or object-oriented or well- encapsulated it is. With tests, we can change the behavior of our code quickly and verifiably. Without them, we really don't know if our code is getting better or worse. - Michael C. Feathers
  • 6. Make New Code Testable
  • 7. How to Initialize Dependency Need Legacy Code New Code
  • 8. Your Code Looks Like This? public class Car { private Engine engine; public Car() { engine = new Engine(); } public void run() { engine.start(); } public String status() { return engine.speed() > 0 ? “Move”: “Stop”; } }
  • 9. Your Test Looks Like This? public class TestCar { @Test public void move() { Car car = new Car(); car.run(); assertEquals(“Move”, car.status()); } } Are you really do the unit test for Car?
  • 10. Code for Car with Isolation public class Car { private IEngine engine; public Car(IEngine theEngine) { engine = theEngine; } public void run() { engine.start(); } public String status() { return engine.speed() > 0 ? “Move”: “Stop”; } }
  • 11. Test for Car with Isolation public class TestCar { @Test public void move() { IEngine engineMock = new EngineMock(10); Car car = new Car(engineMock); car.run(); assertEquals(“Move”, car.status()); } } In fact, you don’t care how engine speed is calculated
  • 12. I Need to Test a Private Method
  • 13. Your Code Looks Like This? public class Order { public void addItem(Item item) { if (isValidItem(item)) { items.add(item); } } private boolean isValidItem(Item item) { more than 500 lines code… } } How can I test the private method?
  • 14. Does Your Class Have too many Responsibilities?
  • 15. Maybe This Code is Better? public class Order { private ItemValidator validator; public Order (ItemValidator theValidator) { validator = theValidator; } public void addItem (Item item) { if (validator. isValidItem(item)) { … } } }
  • 17. “Don’t Do it” unless you have a Very Strong Reason +
  • 18. Good design is testable, and design that isn't testable is bad - Michael C. Feathers
  • 20. Too hard to get Legacy Code under Test
  • 21. Some New Code needed to be added public class Customer { … public void purchase() { more than 500 lines of legacy code… } … } We need to log this customer purchase action after it done. Can you add unit test for new code with no impact to legacy code?
  • 22. Add new code by Sprout Method public class Customer { public void purchase() { purchaseWithoutLog(); logPurchaseAction(); } protected void purchaseWithoutLog() { more than 500 lines of legacy code… } private void logPurchaseAction() { Your new code here… } }
  • 23. Your Test May Look Like This public class TestCustomerPurchaseLog extends Customer { @Test public void log() { Customer customer = new TestCustomerPurchaseLog(); customer.purchase(); … code to verify the log action … } protected void purchaseWithoutLog() {} }
  • 24. Some other Alternative Ways • Sprout Method – the Sample Code • Wrap Method • If the legacy class is hard to be put into test harness o Sprout Class o Wrap Class o This is quite useful when you can’t easily isolate the dependency for legacy class
  • 25. I have a Monster Dependency to Isolate
  • 26. How to Isolate “HttpServletRequest”? public class ARMDispatcher { public void populate (HttpServletRequest request) { String [] values = request.getParameterValues(pageStateName); if (values != null && values.length > 0) { marketBindings.put( pageStateName + getDateStamp(), values[0]); } } }
  • 27. You only Need to get the Parameter Value public class ARMDispatcher { public void populate (ParameterSource source) { String value = source.getParameterForName(pageStateName); if (value != null) { marketBindings.put( ageStateName + getDateStamp(), value); } } }
  • 28. I need D, but it’s from A.getB().getC().getD()
  • 29. Your Code may Look like this public class Customer { private Orders orders; public List<String> getAllItemNamesOfLatestOrder(){ List<String> allNames = new ArrayList<String>(); Item[] items = orders.getLatestOrder().getAllItems(); for (Item item : items) { allNames.add(item.getName()); } return allNames; } }
  • 30. You need to Isolate the way to Get Items public class Customer { private Orders orders; public List<String> getAllItemNamesOfLatestOrder(){ List<String> allNames = new ArrayList<String>(); Item[] items = getAllItemsOfLatestOrder(); for (Item item : items) { allNames.add(item.getName()); } return allNames; } protected Item[] getAllItemsOfLatestOrder() { return orders.getLatestOrder().getAllItems(); } }
  • 32. Test Behavior instead of Test Implementation
  • 34. Q&A 新浪微博 @姚若舟 TDD Code Kata @tudou.com/home/yaoruozhou