SlideShare a Scribd company logo
1 of 42
Download to read offline
Unit Testing Case Study: How Ohio
Mutual Insurance Group Got Started
                 Nick Watts
   Senior Programmer/Analyst for OMIG
   Technical Editor of NFJS, The Magazine
NFJS, The Magazine
• Extension of the No Fluff Just Stuff (NFJS) travelling
  symposium.
• Only NFJS speakers write articles for the magazine.
• Delivered as PDF and ePub file downloads.
• www.nofluffjuststuff.com/home/magazine_subscribe
• @nfjsmag on Twitter.




                  © Copyright, Ohio Mutual Insurance Group   2
Agenda
• Testing Education
• Getting Started in Unit Testing
• Mock Objects




                © Copyright, Ohio Mutual Insurance Group   3
Learn
• Over 2 – 3 years we read articles about,
  attended user group meetings about, took a
  class as part of a Masters degree about and
  attended conference sessions on testing.
• Bewilderment is an appropriate response for
  the first 6 – 12 months (or so).



               © Copyright, Ohio Mutual Insurance Group   4
Learn
• The article that finally made unit testing make
  sense to me:
   – Evolutionary architecture and emergent
     design: Test-driven design, Part 1 by Neal
     Ford.
     • http://www.ibm.com/developerworks/java/library/j-eaed2/




                    © Copyright, Ohio Mutual Insurance Group     5
Practice
• Over the 2 – 3 year learning period we also
  practiced writing unit tests.
• We started with the simplest possible JUnit tests
  we could find to do.
  – Neal Ford asks the question, "What is the simplest
    thing for which I can write a test?"
• Over time we were able to improve and write
  tests for increasingly trickier situations.
• Trying overly-complex tests was a common first
  misstep.
                  © Copyright, Ohio Mutual Insurance Group   6
Understand
• It was absolutely necessary to understand the
  code in order to begin testing it.
• The newest member of the team has been on
  for over 2 years.




                © Copyright, Ohio Mutual Insurance Group   7
Learn, Practice and Understand
• This was a v e r y l o n g process!
• Do not expect to get immediately satisfying
  results.
• Though some people present it so, building a
  significant set of unit tests on an existing code
  base is not easy or quick.



                 © Copyright, Ohio Mutual Insurance Group   8
Reflect
• This all seems so obvious, why am I telling
  you?
  – It helps to hear that someone else went through
    the same experience.
  – Speakers and authors glaze over real details, such
    as “this is REALLY hard to do in REAL life”, to
    remain brief.



                 © Copyright, Ohio Mutual Insurance Group   9
The Case Study
• Real code from a live production system that
  has been in place for over five years.
• Brief analysis of some of the core business
  classes in the system.
• Brief description of major hurdles to writing
  tests against the code.
• Analysis of some methods for testing the code
  before refactoring it.

               © Copyright, Ohio Mutual Insurance Group   10
Why A Case Study?
• Unit testing examples are often trite and too
  far off from reality.
• I believe you either are, were, or will be as
  confused as my team was when we began
  writing unit tests.
• I hope you’ll learn more by seeing real code
  than by seeing contrived examples.


                © Copyright, Ohio Mutual Insurance Group   11
yDoc UML Diagram: Typical Example




          © Copyright, Ohio Mutual Insurance Group   12
yDoc UML Diagram: More Realistic




          © Copyright, Ohio Mutual Insurance Group   13
What is This Mess?
• Core business domain package of a legacy JEE
  system (e-Quip’d™) atop a legacy COBOL
  policy management system (POINT IN).
  – Roughly mirrors the logical view of a “policy” in
    POINT IN.
  – e-Quip’d™ was not built with unit testing in mind.




                 © Copyright, Ohio Mutual Insurance Group   14
What’s the Problem? Or, excuses for
           not unit testing
• “I’m not sure where to start because I can’t
  understand the code.”
  – Complexity
• “I don’t want to write a test that uses static
  data because it’s not a good test.”
  – Validity of Simple Tests




                  © Copyright, Ohio Mutual Insurance Group   15
What’s the Problem? Or, excuses for
           not unit testing
• “It’s too much of a hassle to write a test
  because of all the dependencies.”
  – Unruly Coupling
• “I’m not supposed to write unit tests for
  methods that connect to a database.”
  – Unexpected Database Connections




                 © Copyright, Ohio Mutual Insurance Group   16
Complexity
• This is “the ugly truth” in real code.
  Complexity abounds (both accidental and
  intentional).
• The complexity made the task of testing seem
  hopeless at first. We were unable to decide
  where to start because there is no clear entry
  point.


                © Copyright, Ohio Mutual Insurance Group   17
How We Worked with the Complexity
• Used Old fashioned “elbow grease”.
  – Understood the business domain and the systems
    that support it.
  – Studied the code.
  – Communicated with others who work on the
    system.
• A visualization is very helpful.
  – yDoc is an inexpensive way to start visualizing
    your code in class-sized chunks.
                 © Copyright, Ohio Mutual Insurance Group   18
Basic Policy Class Hierarchy




       © Copyright, Ohio Mutual Insurance Group   19
More Realistic Policy Class Hierarchy




           © Copyright, Ohio Mutual Insurance Group   20
How We Worked with the Complexity
Started simple: Chose the simplest classes we
could find. Usually POJOs and Beans with little
or no business logic.




              © Copyright, Ohio Mutual Insurance Group   21
Example of a Simple Test:
        OMIGSSNumber Class
public class OMIGSSNumberTest {
  public void test_default_constructor() {
     OMIGSSNumber ssn = new OMIGSSNumber();
     assertNotNull(ssn);
     assertNotNull(ssn.getSsNo());
     assertEquals(ssn.getSsNo(), "");
  }
}



              © Copyright, Ohio Mutual Insurance Group   22
Validity of Simple Tests
• At first, we also stumbled just writing some of
  the “simplest” tests.
• Putting static data into tests felt unnatural.
• Tests with static data seemed invalid.




                © Copyright, Ohio Mutual Insurance Group   23
Example of Simple Tests with Static
                Data



public void test_GetModifiedJulianDate() {
  OMIGDate od = new OMIGDate(2008, 8, 16);
  assertEquals(od.getModifiedJulianDate(), 54694);
}




                 © Copyright, Ohio Mutual Insurance Group   24
How We Worked with the Validity of
         Simple Tests
More practice and learning. It just took time
to realize that it was acceptable to build static
test cases that didn’t test all scenarios.




               © Copyright, Ohio Mutual Insurance Group   25
Example of Simple Tests with Static
                 Data

public void test_trans_history_full_constructor() {
   TransactionHistoryRow row = new
        TransactionHistoryRow("01“,"21“,"05“,"CPQ“,
                                   "1234567“,"00“,"0888000“,
                                   "0888z“,"00“,3);
   assertEquals("01", row.getLco());
   assertEquals("21", row.getMco());
   assertEquals("05", row.getPco());
   assertEquals("CPQ", row.getSymbol());
   assertEquals("1234567", row.getNumber());
   assertEquals("00", row.getMod());
   assertEquals("0888000", row.getAgencyId());
   assertEquals("0888z", row.getUserId());
   assertEquals("00", row.getProducerCode());
   assertEquals(3, row.getActivityCode());
}



                       © Copyright, Ohio Mutual Insurance Group   26
Unruly Coupling
• Instantiating an object is unnecessarily
  complex because of coupling.
  – E.g. the BasicContract class constructor requires a
    PolicyKey reference be passed in, which requires
    that a ProductKey reference be passed in, which
    requires five Strings for its constructor.
  – BasicContract is itself used in hundreds of classes.



                  © Copyright, Ohio Mutual Insurance Group   27
Unexpected Database Connections
• Testing a method that connects to a database
  can be troublesome, but can be circumvented.
• A class that connects to a database in a
  constructor is more than troublesome to test
  (i.e. you can’t just ignore a constructor).
  – E.g. PolicyBase




                 © Copyright, Ohio Mutual Insurance Group   28
How We Worked Around Unruly
      Coupling in Unit Tests
You could repeatedly instantiate all of the
objects necessary to create the one you’re
really interested in testing.



This code isn’t un-testable, it’s just a nuisance.



               © Copyright, Ohio Mutual Insurance Group   29
How We Worked Around Unruly
        Coupling in Unit Tests
public void test_basic_contract() {
  ProductKey prodKey =
      new ProductKey("01", "20", "05", "OH", "CPP");
  PolicyKey polKey = new PolicyKey(prodKey);
  BasicContract bc = new BasicContract(polKey);
  assertNotNull(bc);
}




  What about testing classes that require a
  BasicContract reference to instantiate?
                 © Copyright, Ohio Mutual Insurance Group   30
How We Worked Around Unruly
        Coupling in Unit Tests
• Our solution was to just mock the
  troublesome classes and ignore the setup of
  the object.
  – You eventually want to refactor and remove the
    unruly coupling. So start by pretending its not
    there by mocking.




                 © Copyright, Ohio Mutual Insurance Group   32
How We Worked Around Unruly
          Coupling in Unit Tests
public void test_basic_contract_best() {
  BasicContract bc = mock(BasicContract.class);

    assertNotNull(bc);
}




    This is best because it is succinct, doesn’t
    require custom test code and the intent is very
    clear.
                   © Copyright, Ohio Mutual Insurance Group   33
“Mock it and forget it”
• We took the easiest path by just mocking the
  class we wanted to test.
• Most of the object’s state is not needed, so we
  don’t set it up.
  – Notice the deep knowledge of the classes involved
    in this statement.
  – Caution! Carefully consider an object’s internal
    state.


                 © Copyright, Ohio Mutual Insurance Group   34
Mock Objects
• “mocks do not implement any logic: They are
  empty shells that provide methods to let the
  tests control the behavior of all the business
  methods of the faked class. “
  – JUnit in Action, 2nd ed.
• Read about mock objects in JUnit in Action by
  Vincent Massol and Ted Husted and JUnit in
  Action, 2nd ed. by Tachiev et. al.

                  © Copyright, Ohio Mutual Insurance Group   35
Enter Mockito
• Mockito is a mock object framework.
  – Gives you an object that looks like the real object,
    but may or may not, at you discretion, act like the
    real object.
  – Has a very English-like syntax.
  – Very good at working with “legacy” code.
  – www.mockito.org



                  © Copyright, Ohio Mutual Insurance Group   36
Example of Common Mockito Usage in
            OMIG Code
We want to test this method in PolicyBase:


public void putOnHold() throws Exception {
  getBasicContract().setEndType("HLD");
  storeAppInfo();
}




                © Copyright, Ohio Mutual Insurance Group   37
An Attempt at Testing putOnHold()
           Without Mocking


public void test_put_on_hold__sans_mocking() throws
  Exception {
  ProductKey prodKey =
      new ProductKey("01", "20", "06", "RI", "CPP");
  Policy policy = new Policy(prodKey);
  assertTrue(StringUtils.isBlank(
      policy.getBasicContract().getEndType()));
  policy.putOnHold();
  assertTrue(policy.isOnHold());
}                 © Copyright, Ohio Mutual Insurance Group 38
Basic Policy Class Hierarchy




       © Copyright, Ohio Mutual Insurance Group   39
An Attempt at Testing putOnHold()
        Without Mocking
                   Without mocking, the test
                   won’t run because it connects
                   to a database.




          © Copyright, Ohio Mutual Insurance Group   40
Example of Common Mockito Usage in
            OMIG Code
  The previous method is hard to test because of
  unruly coupling and the storeAppInfo() method,
  which connects to a database. The solution…

public void test_put_on_hold() throws Exception {
  Policy policy = mock(Policy.class);
  when(policy.getBasicContract()).
      thenCallRealMethod();
  when(policy.isOnHold()).thenCallRealMethod();
  doCallRealMethod().when(policy).putOnHold();
  …
}


                  © Copyright, Ohio Mutual Insurance Group   41
Summary
• Took our time with unit testing as it was a big
  commitment.
• Started with small, easy unit tests.
• Increased our abilities with learning and
  practice – over time.
• Used mock objects to solve our biggest
  problems.


                © Copyright, Ohio Mutual Insurance Group   42
Contacting Me
• nwatts@omig.com – work email




• @nfjsmag – Twitter (for NFJS, The Magazine)

• Slides at:
  http://www.slideshare.net/thewonggei/unit-
  testing-case-study-cojug05112010

                © Copyright, Ohio Mutual Insurance Group   43

More Related Content

What's hot

Adopting TDD - by Don McGreal
Adopting TDD - by Don McGrealAdopting TDD - by Don McGreal
Adopting TDD - by Don McGrealSynerzip
 
Rethinking the Role of Testers
Rethinking the Role of TestersRethinking the Role of Testers
Rethinking the Role of TestersPaul Gerrard
 
The Axioms of Testing
The Axioms of TestingThe Axioms of Testing
The Axioms of TestingPaul Gerrard
 
Caveon Webinar Series - Discrete Option Multiple Choice: A Revolution in Te...
Caveon Webinar Series  - Discrete Option Multiple Choice:  A Revolution in Te...Caveon Webinar Series  - Discrete Option Multiple Choice:  A Revolution in Te...
Caveon Webinar Series - Discrete Option Multiple Choice: A Revolution in Te...Caveon Test Security
 
Using Stories to Test Requirements and Systems
Using Stories to Test Requirements and SystemsUsing Stories to Test Requirements and Systems
Using Stories to Test Requirements and SystemsPaul Gerrard
 
The Future of Testing
The Future of TestingThe Future of Testing
The Future of TestingPaul Gerrard
 
Maelscrum / Business Story Manager Overview
Maelscrum / Business Story Manager OverviewMaelscrum / Business Story Manager Overview
Maelscrum / Business Story Manager OverviewPaul Gerrard
 
Business Story Method - Overview
Business Story Method - OverviewBusiness Story Method - Overview
Business Story Method - OverviewPaul Gerrard
 
Performance Testing in Context; From Simple to Rocket Science
Performance Testing in Context; From Simple to Rocket SciencePerformance Testing in Context; From Simple to Rocket Science
Performance Testing in Context; From Simple to Rocket ScienceScott Barber
 
2009 06 01 The Lean Startup Texas Edition
2009 06 01 The Lean Startup Texas Edition2009 06 01 The Lean Startup Texas Edition
2009 06 01 The Lean Startup Texas EditionEric Ries
 

What's hot (12)

Adopting TDD - by Don McGreal
Adopting TDD - by Don McGrealAdopting TDD - by Don McGreal
Adopting TDD - by Don McGreal
 
Rethinking the Role of Testers
Rethinking the Role of TestersRethinking the Role of Testers
Rethinking the Role of Testers
 
The Axioms of Testing
The Axioms of TestingThe Axioms of Testing
The Axioms of Testing
 
Caveon Webinar Series - Discrete Option Multiple Choice: A Revolution in Te...
Caveon Webinar Series  - Discrete Option Multiple Choice:  A Revolution in Te...Caveon Webinar Series  - Discrete Option Multiple Choice:  A Revolution in Te...
Caveon Webinar Series - Discrete Option Multiple Choice: A Revolution in Te...
 
Using Stories to Test Requirements and Systems
Using Stories to Test Requirements and SystemsUsing Stories to Test Requirements and Systems
Using Stories to Test Requirements and Systems
 
The Future of Testing
The Future of TestingThe Future of Testing
The Future of Testing
 
Maelscrum / Business Story Manager Overview
Maelscrum / Business Story Manager OverviewMaelscrum / Business Story Manager Overview
Maelscrum / Business Story Manager Overview
 
Business Story Method - Overview
Business Story Method - OverviewBusiness Story Method - Overview
Business Story Method - Overview
 
Elder
ElderElder
Elder
 
Performance Testing in Context; From Simple to Rocket Science
Performance Testing in Context; From Simple to Rocket SciencePerformance Testing in Context; From Simple to Rocket Science
Performance Testing in Context; From Simple to Rocket Science
 
2009 06 01 The Lean Startup Texas Edition
2009 06 01 The Lean Startup Texas Edition2009 06 01 The Lean Startup Texas Edition
2009 06 01 The Lean Startup Texas Edition
 
Leadership
LeadershipLeadership
Leadership
 

Similar to Unit Testing Case Study for COJUG - 05.11.2010

assertYourself - Breaking the Theories and Assumptions of Unit Testing in Flex
assertYourself - Breaking the Theories and Assumptions of Unit Testing in FlexassertYourself - Breaking the Theories and Assumptions of Unit Testing in Flex
assertYourself - Breaking the Theories and Assumptions of Unit Testing in Flexmichael.labriola
 
How to test a Mainframe Application
How to test a Mainframe ApplicationHow to test a Mainframe Application
How to test a Mainframe ApplicationMichael Erichsen
 
Unit testing
Unit testingUnit testing
Unit testingPiXeL16
 
Test driven development
Test driven developmentTest driven development
Test driven developmentnamkha87
 
Test driven development
Test driven developmentTest driven development
Test driven developmentSunil Prasad
 
Annotated Bibliography .Guidelines Annotated Bibliograph.docx
Annotated Bibliography  .Guidelines Annotated Bibliograph.docxAnnotated Bibliography  .Guidelines Annotated Bibliograph.docx
Annotated Bibliography .Guidelines Annotated Bibliograph.docxjustine1simpson78276
 
AiTi Education Software Testing Session 01 a
AiTi Education Software Testing Session 01 aAiTi Education Software Testing Session 01 a
AiTi Education Software Testing Session 01 aAiTi Education
 
So You Think You Can Write a Test Case - XBOSoft Webinar
So You Think You Can Write a Test Case - XBOSoft WebinarSo You Think You Can Write a Test Case - XBOSoft Webinar
So You Think You Can Write a Test Case - XBOSoft WebinarXBOSoft
 
Agile Mumbai 2020 Conference | How to get the best ROI on Your Test Automati...
Agile Mumbai 2020 Conference |  How to get the best ROI on Your Test Automati...Agile Mumbai 2020 Conference |  How to get the best ROI on Your Test Automati...
Agile Mumbai 2020 Conference | How to get the best ROI on Your Test Automati...AgileNetwork
 
Software Engineering Practice - Software Quality Management
Software Engineering Practice - Software Quality ManagementSoftware Engineering Practice - Software Quality Management
Software Engineering Practice - Software Quality ManagementRadu_Negulescu
 
How To Handle Your Tech Debt Better - Sean Moir
How To Handle Your Tech Debt Better - Sean MoirHow To Handle Your Tech Debt Better - Sean Moir
How To Handle Your Tech Debt Better - Sean MoirMike Harris
 
Eric Ries Lean Startup Presentation For Web 2.0 Expo April 1 2009 A Disciplin...
Eric Ries Lean Startup Presentation For Web 2.0 Expo April 1 2009 A Disciplin...Eric Ries Lean Startup Presentation For Web 2.0 Expo April 1 2009 A Disciplin...
Eric Ries Lean Startup Presentation For Web 2.0 Expo April 1 2009 A Disciplin...Eric Ries
 
Testing micro services using testkits
Testing micro services using testkitsTesting micro services using testkits
Testing micro services using testkitsMaxim Novak
 
Achieve Intelligent Test Execution: Strategies for Streamlining Regression Te...
Achieve Intelligent Test Execution: Strategies for Streamlining Regression Te...Achieve Intelligent Test Execution: Strategies for Streamlining Regression Te...
Achieve Intelligent Test Execution: Strategies for Streamlining Regression Te...DevOps.com
 
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...Abdelkrim Boujraf
 
Adopting Agile
Adopting AgileAdopting Agile
Adopting AgileCoverity
 
Top 15 reasons to choose qa testing as career
Top 15 reasons to choose qa testing as career Top 15 reasons to choose qa testing as career
Top 15 reasons to choose qa testing as career JanBask Training
 
2009 05 21 The Lean Startup At SIPA
2009 05 21 The Lean Startup At SIPA2009 05 21 The Lean Startup At SIPA
2009 05 21 The Lean Startup At SIPAEric Ries
 
Exploratory Testing Explained
Exploratory Testing ExplainedExploratory Testing Explained
Exploratory Testing ExplainedTechWell
 

Similar to Unit Testing Case Study for COJUG - 05.11.2010 (20)

assertYourself - Breaking the Theories and Assumptions of Unit Testing in Flex
assertYourself - Breaking the Theories and Assumptions of Unit Testing in FlexassertYourself - Breaking the Theories and Assumptions of Unit Testing in Flex
assertYourself - Breaking the Theories and Assumptions of Unit Testing in Flex
 
How to test a Mainframe Application
How to test a Mainframe ApplicationHow to test a Mainframe Application
How to test a Mainframe Application
 
Unit testing
Unit testingUnit testing
Unit testing
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Annotated Bibliography .Guidelines Annotated Bibliograph.docx
Annotated Bibliography  .Guidelines Annotated Bibliograph.docxAnnotated Bibliography  .Guidelines Annotated Bibliograph.docx
Annotated Bibliography .Guidelines Annotated Bibliograph.docx
 
AiTi Education Software Testing Session 01 a
AiTi Education Software Testing Session 01 aAiTi Education Software Testing Session 01 a
AiTi Education Software Testing Session 01 a
 
So You Think You Can Write a Test Case - XBOSoft Webinar
So You Think You Can Write a Test Case - XBOSoft WebinarSo You Think You Can Write a Test Case - XBOSoft Webinar
So You Think You Can Write a Test Case - XBOSoft Webinar
 
Agile Mumbai 2020 Conference | How to get the best ROI on Your Test Automati...
Agile Mumbai 2020 Conference |  How to get the best ROI on Your Test Automati...Agile Mumbai 2020 Conference |  How to get the best ROI on Your Test Automati...
Agile Mumbai 2020 Conference | How to get the best ROI on Your Test Automati...
 
Software Engineering Practice - Software Quality Management
Software Engineering Practice - Software Quality ManagementSoftware Engineering Practice - Software Quality Management
Software Engineering Practice - Software Quality Management
 
How To Handle Your Tech Debt Better - Sean Moir
How To Handle Your Tech Debt Better - Sean MoirHow To Handle Your Tech Debt Better - Sean Moir
How To Handle Your Tech Debt Better - Sean Moir
 
Eric Ries Lean Startup Presentation For Web 2.0 Expo April 1 2009 A Disciplin...
Eric Ries Lean Startup Presentation For Web 2.0 Expo April 1 2009 A Disciplin...Eric Ries Lean Startup Presentation For Web 2.0 Expo April 1 2009 A Disciplin...
Eric Ries Lean Startup Presentation For Web 2.0 Expo April 1 2009 A Disciplin...
 
Tdd dev session
Tdd dev sessionTdd dev session
Tdd dev session
 
Testing micro services using testkits
Testing micro services using testkitsTesting micro services using testkits
Testing micro services using testkits
 
Achieve Intelligent Test Execution: Strategies for Streamlining Regression Te...
Achieve Intelligent Test Execution: Strategies for Streamlining Regression Te...Achieve Intelligent Test Execution: Strategies for Streamlining Regression Te...
Achieve Intelligent Test Execution: Strategies for Streamlining Regression Te...
 
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
 
Adopting Agile
Adopting AgileAdopting Agile
Adopting Agile
 
Top 15 reasons to choose qa testing as career
Top 15 reasons to choose qa testing as career Top 15 reasons to choose qa testing as career
Top 15 reasons to choose qa testing as career
 
2009 05 21 The Lean Startup At SIPA
2009 05 21 The Lean Startup At SIPA2009 05 21 The Lean Startup At SIPA
2009 05 21 The Lean Startup At SIPA
 
Exploratory Testing Explained
Exploratory Testing ExplainedExploratory Testing Explained
Exploratory Testing Explained
 

Recently uploaded

TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc
 
Generative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfGenerative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfalexjohnson7307
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch TuesdayIvanti
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsLeah Henrickson
 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Skynet Technologies
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)Samir Dash
 
AI mind or machine power point presentation
AI mind or machine power point presentationAI mind or machine power point presentation
AI mind or machine power point presentationyogeshlabana357357
 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfSrushith Repakula
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024Lorenzo Miniero
 
JavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuideJavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuidePixlogix Infotech
 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceSamy Fodil
 
Design Guidelines for Passkeys 2024.pptx
Design Guidelines for Passkeys 2024.pptxDesign Guidelines for Passkeys 2024.pptx
Design Guidelines for Passkeys 2024.pptxFIDO Alliance
 
الأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهلهالأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهلهMohamed Sweelam
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMKumar Satyam
 
Intro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptxIntro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptxFIDO Alliance
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data SciencePaolo Missier
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityVictorSzoltysek
 
Introduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxIntroduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxFIDO Alliance
 
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...ScyllaDB
 
Easier, Faster, and More Powerful – Notes Document Properties Reimagined
Easier, Faster, and More Powerful – Notes Document Properties ReimaginedEasier, Faster, and More Powerful – Notes Document Properties Reimagined
Easier, Faster, and More Powerful – Notes Document Properties Reimaginedpanagenda
 

Recently uploaded (20)

TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
 
Generative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfGenerative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdf
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch Tuesday
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
AI mind or machine power point presentation
AI mind or machine power point presentationAI mind or machine power point presentation
AI mind or machine power point presentation
 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdf
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024
 
JavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuideJavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate Guide
 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM Performance
 
Design Guidelines for Passkeys 2024.pptx
Design Guidelines for Passkeys 2024.pptxDesign Guidelines for Passkeys 2024.pptx
Design Guidelines for Passkeys 2024.pptx
 
الأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهلهالأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهله
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
Intro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptxIntro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptx
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data Science
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps Productivity
 
Introduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxIntroduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptx
 
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
 
Easier, Faster, and More Powerful – Notes Document Properties Reimagined
Easier, Faster, and More Powerful – Notes Document Properties ReimaginedEasier, Faster, and More Powerful – Notes Document Properties Reimagined
Easier, Faster, and More Powerful – Notes Document Properties Reimagined
 

Unit Testing Case Study for COJUG - 05.11.2010

  • 1. Unit Testing Case Study: How Ohio Mutual Insurance Group Got Started Nick Watts Senior Programmer/Analyst for OMIG Technical Editor of NFJS, The Magazine
  • 2. NFJS, The Magazine • Extension of the No Fluff Just Stuff (NFJS) travelling symposium. • Only NFJS speakers write articles for the magazine. • Delivered as PDF and ePub file downloads. • www.nofluffjuststuff.com/home/magazine_subscribe • @nfjsmag on Twitter. © Copyright, Ohio Mutual Insurance Group 2
  • 3. Agenda • Testing Education • Getting Started in Unit Testing • Mock Objects © Copyright, Ohio Mutual Insurance Group 3
  • 4. Learn • Over 2 – 3 years we read articles about, attended user group meetings about, took a class as part of a Masters degree about and attended conference sessions on testing. • Bewilderment is an appropriate response for the first 6 – 12 months (or so). © Copyright, Ohio Mutual Insurance Group 4
  • 5. Learn • The article that finally made unit testing make sense to me: – Evolutionary architecture and emergent design: Test-driven design, Part 1 by Neal Ford. • http://www.ibm.com/developerworks/java/library/j-eaed2/ © Copyright, Ohio Mutual Insurance Group 5
  • 6. Practice • Over the 2 – 3 year learning period we also practiced writing unit tests. • We started with the simplest possible JUnit tests we could find to do. – Neal Ford asks the question, "What is the simplest thing for which I can write a test?" • Over time we were able to improve and write tests for increasingly trickier situations. • Trying overly-complex tests was a common first misstep. © Copyright, Ohio Mutual Insurance Group 6
  • 7. Understand • It was absolutely necessary to understand the code in order to begin testing it. • The newest member of the team has been on for over 2 years. © Copyright, Ohio Mutual Insurance Group 7
  • 8. Learn, Practice and Understand • This was a v e r y l o n g process! • Do not expect to get immediately satisfying results. • Though some people present it so, building a significant set of unit tests on an existing code base is not easy or quick. © Copyright, Ohio Mutual Insurance Group 8
  • 9. Reflect • This all seems so obvious, why am I telling you? – It helps to hear that someone else went through the same experience. – Speakers and authors glaze over real details, such as “this is REALLY hard to do in REAL life”, to remain brief. © Copyright, Ohio Mutual Insurance Group 9
  • 10. The Case Study • Real code from a live production system that has been in place for over five years. • Brief analysis of some of the core business classes in the system. • Brief description of major hurdles to writing tests against the code. • Analysis of some methods for testing the code before refactoring it. © Copyright, Ohio Mutual Insurance Group 10
  • 11. Why A Case Study? • Unit testing examples are often trite and too far off from reality. • I believe you either are, were, or will be as confused as my team was when we began writing unit tests. • I hope you’ll learn more by seeing real code than by seeing contrived examples. © Copyright, Ohio Mutual Insurance Group 11
  • 12. yDoc UML Diagram: Typical Example © Copyright, Ohio Mutual Insurance Group 12
  • 13. yDoc UML Diagram: More Realistic © Copyright, Ohio Mutual Insurance Group 13
  • 14. What is This Mess? • Core business domain package of a legacy JEE system (e-Quip’d™) atop a legacy COBOL policy management system (POINT IN). – Roughly mirrors the logical view of a “policy” in POINT IN. – e-Quip’d™ was not built with unit testing in mind. © Copyright, Ohio Mutual Insurance Group 14
  • 15. What’s the Problem? Or, excuses for not unit testing • “I’m not sure where to start because I can’t understand the code.” – Complexity • “I don’t want to write a test that uses static data because it’s not a good test.” – Validity of Simple Tests © Copyright, Ohio Mutual Insurance Group 15
  • 16. What’s the Problem? Or, excuses for not unit testing • “It’s too much of a hassle to write a test because of all the dependencies.” – Unruly Coupling • “I’m not supposed to write unit tests for methods that connect to a database.” – Unexpected Database Connections © Copyright, Ohio Mutual Insurance Group 16
  • 17. Complexity • This is “the ugly truth” in real code. Complexity abounds (both accidental and intentional). • The complexity made the task of testing seem hopeless at first. We were unable to decide where to start because there is no clear entry point. © Copyright, Ohio Mutual Insurance Group 17
  • 18. How We Worked with the Complexity • Used Old fashioned “elbow grease”. – Understood the business domain and the systems that support it. – Studied the code. – Communicated with others who work on the system. • A visualization is very helpful. – yDoc is an inexpensive way to start visualizing your code in class-sized chunks. © Copyright, Ohio Mutual Insurance Group 18
  • 19. Basic Policy Class Hierarchy © Copyright, Ohio Mutual Insurance Group 19
  • 20. More Realistic Policy Class Hierarchy © Copyright, Ohio Mutual Insurance Group 20
  • 21. How We Worked with the Complexity Started simple: Chose the simplest classes we could find. Usually POJOs and Beans with little or no business logic. © Copyright, Ohio Mutual Insurance Group 21
  • 22. Example of a Simple Test: OMIGSSNumber Class public class OMIGSSNumberTest { public void test_default_constructor() { OMIGSSNumber ssn = new OMIGSSNumber(); assertNotNull(ssn); assertNotNull(ssn.getSsNo()); assertEquals(ssn.getSsNo(), ""); } } © Copyright, Ohio Mutual Insurance Group 22
  • 23. Validity of Simple Tests • At first, we also stumbled just writing some of the “simplest” tests. • Putting static data into tests felt unnatural. • Tests with static data seemed invalid. © Copyright, Ohio Mutual Insurance Group 23
  • 24. Example of Simple Tests with Static Data public void test_GetModifiedJulianDate() { OMIGDate od = new OMIGDate(2008, 8, 16); assertEquals(od.getModifiedJulianDate(), 54694); } © Copyright, Ohio Mutual Insurance Group 24
  • 25. How We Worked with the Validity of Simple Tests More practice and learning. It just took time to realize that it was acceptable to build static test cases that didn’t test all scenarios. © Copyright, Ohio Mutual Insurance Group 25
  • 26. Example of Simple Tests with Static Data public void test_trans_history_full_constructor() { TransactionHistoryRow row = new TransactionHistoryRow("01“,"21“,"05“,"CPQ“, "1234567“,"00“,"0888000“, "0888z“,"00“,3); assertEquals("01", row.getLco()); assertEquals("21", row.getMco()); assertEquals("05", row.getPco()); assertEquals("CPQ", row.getSymbol()); assertEquals("1234567", row.getNumber()); assertEquals("00", row.getMod()); assertEquals("0888000", row.getAgencyId()); assertEquals("0888z", row.getUserId()); assertEquals("00", row.getProducerCode()); assertEquals(3, row.getActivityCode()); } © Copyright, Ohio Mutual Insurance Group 26
  • 27. Unruly Coupling • Instantiating an object is unnecessarily complex because of coupling. – E.g. the BasicContract class constructor requires a PolicyKey reference be passed in, which requires that a ProductKey reference be passed in, which requires five Strings for its constructor. – BasicContract is itself used in hundreds of classes. © Copyright, Ohio Mutual Insurance Group 27
  • 28. Unexpected Database Connections • Testing a method that connects to a database can be troublesome, but can be circumvented. • A class that connects to a database in a constructor is more than troublesome to test (i.e. you can’t just ignore a constructor). – E.g. PolicyBase © Copyright, Ohio Mutual Insurance Group 28
  • 29. How We Worked Around Unruly Coupling in Unit Tests You could repeatedly instantiate all of the objects necessary to create the one you’re really interested in testing. This code isn’t un-testable, it’s just a nuisance. © Copyright, Ohio Mutual Insurance Group 29
  • 30. How We Worked Around Unruly Coupling in Unit Tests public void test_basic_contract() { ProductKey prodKey = new ProductKey("01", "20", "05", "OH", "CPP"); PolicyKey polKey = new PolicyKey(prodKey); BasicContract bc = new BasicContract(polKey); assertNotNull(bc); } What about testing classes that require a BasicContract reference to instantiate? © Copyright, Ohio Mutual Insurance Group 30
  • 31. How We Worked Around Unruly Coupling in Unit Tests • Our solution was to just mock the troublesome classes and ignore the setup of the object. – You eventually want to refactor and remove the unruly coupling. So start by pretending its not there by mocking. © Copyright, Ohio Mutual Insurance Group 32
  • 32. How We Worked Around Unruly Coupling in Unit Tests public void test_basic_contract_best() { BasicContract bc = mock(BasicContract.class); assertNotNull(bc); } This is best because it is succinct, doesn’t require custom test code and the intent is very clear. © Copyright, Ohio Mutual Insurance Group 33
  • 33. “Mock it and forget it” • We took the easiest path by just mocking the class we wanted to test. • Most of the object’s state is not needed, so we don’t set it up. – Notice the deep knowledge of the classes involved in this statement. – Caution! Carefully consider an object’s internal state. © Copyright, Ohio Mutual Insurance Group 34
  • 34. Mock Objects • “mocks do not implement any logic: They are empty shells that provide methods to let the tests control the behavior of all the business methods of the faked class. “ – JUnit in Action, 2nd ed. • Read about mock objects in JUnit in Action by Vincent Massol and Ted Husted and JUnit in Action, 2nd ed. by Tachiev et. al. © Copyright, Ohio Mutual Insurance Group 35
  • 35. Enter Mockito • Mockito is a mock object framework. – Gives you an object that looks like the real object, but may or may not, at you discretion, act like the real object. – Has a very English-like syntax. – Very good at working with “legacy” code. – www.mockito.org © Copyright, Ohio Mutual Insurance Group 36
  • 36. Example of Common Mockito Usage in OMIG Code We want to test this method in PolicyBase: public void putOnHold() throws Exception { getBasicContract().setEndType("HLD"); storeAppInfo(); } © Copyright, Ohio Mutual Insurance Group 37
  • 37. An Attempt at Testing putOnHold() Without Mocking public void test_put_on_hold__sans_mocking() throws Exception { ProductKey prodKey = new ProductKey("01", "20", "06", "RI", "CPP"); Policy policy = new Policy(prodKey); assertTrue(StringUtils.isBlank( policy.getBasicContract().getEndType())); policy.putOnHold(); assertTrue(policy.isOnHold()); } © Copyright, Ohio Mutual Insurance Group 38
  • 38. Basic Policy Class Hierarchy © Copyright, Ohio Mutual Insurance Group 39
  • 39. An Attempt at Testing putOnHold() Without Mocking Without mocking, the test won’t run because it connects to a database. © Copyright, Ohio Mutual Insurance Group 40
  • 40. Example of Common Mockito Usage in OMIG Code The previous method is hard to test because of unruly coupling and the storeAppInfo() method, which connects to a database. The solution… public void test_put_on_hold() throws Exception { Policy policy = mock(Policy.class); when(policy.getBasicContract()). thenCallRealMethod(); when(policy.isOnHold()).thenCallRealMethod(); doCallRealMethod().when(policy).putOnHold(); … } © Copyright, Ohio Mutual Insurance Group 41
  • 41. Summary • Took our time with unit testing as it was a big commitment. • Started with small, easy unit tests. • Increased our abilities with learning and practice – over time. • Used mock objects to solve our biggest problems. © Copyright, Ohio Mutual Insurance Group 42
  • 42. Contacting Me • nwatts@omig.com – work email • @nfjsmag – Twitter (for NFJS, The Magazine) • Slides at: http://www.slideshare.net/thewonggei/unit- testing-case-study-cojug05112010 © Copyright, Ohio Mutual Insurance Group 43