Pragmatic Unit Testing in Java with JUnit, Third Edition
by Jeff Langr
The classic Pragmatic Unit Testing with Java in JUnit returns for a
third edition, streamlined and rewritten with updated and more
accessible code examples. In this edition, you’ll learn how to create
concise, maintainable unit tests with confidence. New chapters provide a
foundation of examples for testing common concepts, and guidance on
incorporating modern AI tools into your development and testing. Updated
topics include improving test quality via development mnemonics,
increasing ROI through test and production code refactoring, and using
tests to drive development.
Pragmatic Unit Testing in Java with JUnit steps you through all the
important unit testing topics.
If you’ve never written a unit test, you’ll be hand-held through the
hard part—getting set up and started. Once past the basics, you’ll see
numerous examples in order to start understanding what tests for common
code concepts look like. You’ll then learn how to effectively use the
essential features of JUnit, the predominant tool for writing and
executing unit tests in Java.
You’ll gain the combined wisdom of Jeff Langr and original authors Andy
Hunt and Dave Thomas, providing decades of unit testing experience on
real production systems. You’ll learn how to:
- Craft your code to make unit testing easier in the first place
- Craft your unit tests to minimize your maintenance effort
- Use unit tests to support keeping your system clean through
refactoring
- Refactor toward a design that will create the highest possible ROI
- Test the tough stuff, including code that must be mocked
- Remember what’s important when writing unit tests
- Help your team reap and sustain the benefits of unit testing
- Use AI tooling as part of a development process that incorporates
unit testing
You won’t just learn about unit testing in theory—you’ll learn about
“real” unit testing the Pragmatic way by working through numerous code
examples.
What You Need
You’ll need the Java SDK (Software Development Kit) version 21 or higher
to work through the examples in the book. You’ll also want an IDE
(Integrated Development Environment) in which to build code. While most
of the book doesn’t assume use of any specific IDE, you’ll find a number
of “getting started” screen shots to help you if you’re using IntelliJ
IDEA.
Resources
Releases:
- P1.0 2024/11/13
- B3.0 2024/10/29
- B2.0 2024/08/26
- B1.0 2024/07/29
Preface
- Unit Testing Foundations
- Building Your First JUnit Test
- Reasons to Write a Unit Test
- Learning JUnit Basics: Your First Testing Challenge
- Writing a First Real Test
- Dealing with Failure
- Moving On to a One-Based Test: Something’s Happening!
- Increasing Your ROI: Cleaning Up Tests
- ZOM: Zero and One Done, Now Testing Many
- Covering Other Cases: Creating a Test List
- Congratulations!…But Don’t Stop Yet
- Testing the Building Blocks
- Units
- A Wee Bit Bigger Than a Unit?
- Concepts as Building Blocks
- Testing the Simpler Things
- Verifying Side Effects
- Testing Common Code Circumstances
- Exploring Boundaries with CORRECT
- Summary
- Using Test Doubles
- A Testing Challenge
- Replacing Troublesome Behavior with Stubs
- Changing Your Design to Support Testing
- Adding Smarts to Your Stub: Verifying Parameters
- Simplifying Testing Using a Mock Tool
- Injecting Mocks with Mockito
- Verifying a Method Was Called…or Not
- Testing Exception Handling
- Fast Tests
- A Mélange of Important Test Double Tips
- Summary
- Expanding Your Testing Horizons
- Improving Unit Testing Skills Using Code Coverage
- Testing Multithreaded Code
- Writing Integration Tests
- Exploratory Unit Testing
- Summary
- Mastering JUnit with “E"s
- Examining Outcomes with Assertions
- Using the Core Assertion
Forms
- Assertion Messages: Redundant Messages for Assertions
- Other Common JUnit Assertion Forms
- Expecting Exceptions
- Assert That Nothing Happened: assertDoesNotThrow
- Alternate Assertion Approaches
- Third-Party Assertion Libraries
- Eliminating Non-Tests
- Summary
- Establishing Organization in JUnit Tests
- The Parts of an Individual Test
- Setting Up and Tearing Down Using Lifecycle Methods
- Organizing Related Tests into Nested
Classes
- Avoiding Dependency Despair: Don’t Order Your Tests!
- Executing Multiple Data Cases with Parameterized Tests
- Summary
- Executing JUnit Tests
- Testing Habits: What Tests to Run
- Creating Arbitrary Test Groups Using Tags
- Temporarily Disabling Tests with @Disabled
- Exploring More Features
- Summary
- Increasing ROI: Unit Testing and Design
- Refactoring to Cleaner Code
- A Little Bit o’ Refactor
- Finding Better Homes for Your Methods
- Removing Temporaries of Little Value
- Amplifying the Core Intent of
Code
- Are You Kidding Me? Addressing Concerns over Performance
- Final Cleanup
- Summary
- Refactoring Your Code’s Structure
- The Profile Class and the SRP
- Extracting a New Class
- Command-Query Separation
- The Costs of Maintaining Unit Tests
- Summary
- Streamlining Your Tests
- Tests as Documentation
- Searching for an Understanding
- Test Smell: Legacy Code Constructs
- Test Smell: Unnecessary Test Code
- Test Smells: Generalized and Stepwise Assertions
- Test Smell: Missing Abstractions
- Test Smell: Bloated Construction
- Test Smell: Multiple Assertions
- Test Smell: Irrelevant Details in a Test
- Test Smell: Misleading Organization
- Test Smell: Implicit Meaning
- Adding Tests from Your Test List
- Summary
- Bigger Topics Around Unit Testing
- Advancing with Test-Driven Development (TDD)
- The Primary Benefit of TDD
- Starting Simple
- Increment 1: Deferring Complexity
- Increment 2: Generalizing the Implementation
- Increment 3: Factoring Out Redundancies
- Increment 4: Introducing a Test Double
- Test-Driven Development vs. Test-After Development
- The Rhythm of TDD
- Summary
- Adopting Team Practices
- Coming up to Speed
- Getting on the Same Page with Your Team
- Practicing Continuous Integration
- Summary
- Keeping AI Honest with Unit Tests
- AI Isn’t Going Away
- Exploring a Simple Example with ChatGPT
- Establishing a Java Standard
- Providing Examples to ChatGPT
- Telling Your LLM to Clean Up Its Act
- Adding a New Feature: Suffixes
- Getting the LLM to Do Final Design Cleanup
- For Extra Credit
- Increasing Odds of Success with AI-Generated Code
- Will I Go Faster?
- Summary
Author
Jeff Langr is a veteran software developer with 40+ years experience
building software. Jeff provides consulting, training, development, and
coaching to customers through Langr Software Solutions, Inc. Jeff also
wrote Agile in a
Flash (with Tim
Ottinger) and Modern C++ Programming with Test-Driven
Development
for the Pragmatic Bookshelf.