One of the biggest challenges developers encounter in their career is having to maintain an existing codebase with little or no tests and unclear, tangled code. In this course, Unit Testing Legacy Code in Java, you will learn techniques to get a legacy and untested Java application, a small but realistic Java application to provide services to a hospital emergency room, under test incrementally as you work on it. First, you will learn about different types of tests and test doubles that can be applied to create a safety net for the application gradually. Next, you will discover crucial dependency-breaking techniques that will allow you to create seams to provide test doubles without disrupting the code. Finally, you will explore ways to deal with hard to understand code, improving the clarity as you work, and techniques to leverage new, tested code from hard to understand code. When you are finished with this course, you will have the knowledge to efficiently handle untested systems you’ve become responsible for.
Course Overview Hi everyone! I'm Jim Weaver for Pluralsight. In the course of my career, I've met my fair share of ugly, hard-to-test code. Such code's tough to work with, and being responsible for a whole code base of untested code can be challenging and intimidating. In this course, Unit Testing Legacy Code with Java, we're going to face just such a challenge together. We'll be asked to maintain a Java application that provides services to a hospital's emergency room operations. This business critical code base isn't particularly well written. And there isn't an automated test of any kind in sight. But our customer has pressing changes that need to be made. During this course, we'll learn a variety of techniques to tackle the biggest part of the legacy code problem, breaking dependencies between units of code that make testing difficult. The techniques we'll learn will allow us to get code under test with small, targeted conservative changes that don't disrupt other parts of the system. We won't be telling our customer to wait while we rewrite parts from scratch. We'll also learn techniques to improve the clarity of hard-to-understand code with low-risk changes until we can get a test in place, and we'll see how higher level tests can help improve our safety net as we gradually get code unit testable. By the end of this course, you'll have learned a toolkit's worth of techniques that will help you tackle untested legacy code bases. So come join me for unit testing legacy code in Java.
Introducing Our Legacy System Hi! This is Jim Weaver for Pluralsight, and this course is Unit Testing Legacy Code in Java. In this introductory module, we'll discuss several definitions of legacy code and why tests are important to get in place for a legacy system. We'll get an introduction to the legacy system we're being asked to modify, which will serve as our example system throughout the course. And most importantly, we'll discuss our strategy for maintaining and modifying our legacy system without breaking it so badly that we lose our jobs.
Understanding the Role of Different Types of Tests Before we begin wrestling with code, it's a good idea to have a strategy in mind. Understanding the different types of tests we can apply to our legacy system will help us form that strategy. In this module, we'll learn about different types of tests by granularity, audience, and purpose. We'll check out the ERServer sample project and demonstrate those different types of tests. And, finally, we'll formulate our high-level strategy for testing ERServer.
Testing Code with Problematic Dependencies Now that we have a high-level strategy in mind to tackle getting tests in place for our legacy system, we need to learn how to deal with our biggest challenge--dependencies between units of code that make testing difficult. In this module, we'll learn about different types of test doubles and their use and how test doubles can be provided to the code under test through the application of dependency injection. Then we'll learn a number of techniques to break dependencies allowing us to avoid them while testing or provide test doubles. We'll apply these techniques while adding functionality to ERServer, our legacy system. So while adding functionality our customer wants, we'll also be creating a test safety net to help us avoid breaking existing functionality and increase our ability to confidently refactor code in the future.
Testing Hard to Understand Code Now that we've learned some techniques to get code with difficult dependencies under test, let's tackle our next challenge. Code can be difficult to test and, therefore, risky to modify simply because it's a mess, it's hard to understand. In this module, we'll discuss some of the challenges when working with confusing, lengthy, or tangled code. Then we'll apply some basic techniques to improve the clarity of such code along with some techniques to avoid adding too much to hard-to-understand code by directing modifications to new methods or classes. Throughout this module, we'll continue improving ERServer by adding test coverage and improving the clarity of the code that we need to change to add features for our customer.
Expanding Your Skills We did quite a bit of work on our legacy system in the previous modules learning techniques to get code under test as we went. Is there more we can learn that will help us work with legacy code bases? Of course there is. In this module, we'll summarize our progress and accomplishments on ERServer. And we'll discuss some code in the application that still needs some work. And we'll provide a good way to practice our new skills. Finally, we'll discuss some additional materials that can provide us with even more skills to apply when working with legacy systems.