Test-Driven Development with Java

Book description

Drive development with automated tests and gain the confidence you need to write high-quality software

Key Features

  • Get up and running with common design patterns and TDD best practices
  • Learn to apply the rhythms of TDD – arrange, act, assert and red, green, refactor
  • Understand the challenges of implementing TDD in the Java ecosystem and build a plan

Book Description

Test-driven development enables developers to craft well-designed code and prevent defects. It's a simple yet powerful tool that helps you focus on your code design, while automatically checking that your code works correctly. Mastering TDD will enable you to effectively utilize design patterns and become a proficient software architect.

The book begins by explaining the basics of good code and bad code, bursting common myths, and why Test-driven development is crucial. You'll then gradually move toward building a sample application using TDD, where you'll apply the two key rhythms -- red, green, refactor and arrange, act, assert. Next, you'll learn how to bring external systems such as databases under control by using dependency inversion and test doubles. As you advance, you'll delve into advanced design techniques such as SOLID patterns, refactoring, and hexagonal architecture. You'll also balance your use of fast, repeatable unit tests against integration tests using the test pyramid as a guide. The concluding chapters will show you how to implement TDD in real-world use cases and scenarios and develop a modern REST microservice backed by a Postgres database in Java 17.

By the end of this book, you'll be thinking differently about how you design code for simplicity and how correctness can be baked in as you go.

What you will learn

  • Discover how to write effective test cases in Java
  • Explore how TDD can be incorporated into crafting software
  • Find out how to write reusable and robust code in Java
  • Uncover common myths about TDD and understand its effectiveness
  • Understand the accurate rhythm of implementing TDD
  • Get to grips with the process of refactoring and see how it affects the TDD process

Who this book is for

This book is for expert Java developers and software architects crafting high-quality software in Java. Test-Driven Development with Java can be picked up by anyone with a strong working experience in Java who is planning to use Test-driven development for their upcoming projects.

Table of contents

  1. Test-Driven Development with Java
  2. Contributors
  3. About the author
  4. About the reviewers
  5. Preface
    1. Who this book is for
    2. What this book covers
    3. To get the most out of this book
    4. Download the example code files
    5. Download the color images
    6. Conventions used
    7. Get in touch
    8. Share Your Thoughts
    9. Download a free PDF copy of this book
  6. Part 1: How We Got to TDD
  7. Chapter 1: Building the Case for TDD
    1. Writing code badly
      1. Understanding why bad code is written
    2. Recognizing bad code
      1. Bad variable names
      2. Bad function, method, and class names
      3. Error-prone constructs
      4. Coupling and cohesion
    3. Decreasing team performance
    4. Diminishing business outcomes
    5. Summary
    6. Questions and answers
    7. Further reading
  8. Chapter 2: Using TDD to Create Good Code
    1. Designing good quality code
      1. Say what you mean, mean what you say
      2. Take care of the details in private
      3. Avoid accidental complexity
    2. Revealing design flaws
      1. Analyzing the benefits of writing tests before production code
    3. Preventing logic flaws
    4. Protecting against future defects
    5. Documenting our code
    6. Summary
    7. Questions and answers
    8. Further reading
  9. Chapter 3: Dispelling Common Myths about TDD
    1. Writing tests slows me down
      1. Understanding the benefits of slowing down
      2. Overcoming objections to tests slowing us down
    2. Tests cannot prevent every bug
      1. Understanding why people say tests cannot catch every bug
      2. Overcoming objections to not catching every bug
    3. How do you know the tests are right?
      1. Understanding the concerns behind writing broken tests
      2. Providing reassurance that we test our tests
    4. TDD guarantees good code
      1. Understanding problem-inflated expectations
      2. Managing your expectations of TDD
    5. Our code is too complex to test
      1. Understanding the causes of untestable code
      2. Reframing the relationship between good design and simple tests
      3. Managing legacy code without tests
    6. I don’t know what to test until I write the code
      1. Understanding the difficulty of starting with testing
      2. Overcoming the need to write production code first
    7. Summary
    8. Questions and answers
    9. Further reading
  10. Part 2: TDD Techniques
  11. Chapter 4: Building an Application Using TDD
    1. Technical requirements
      1. Preparing our development environment
      2. Installing the IntelliJ IDE
      3. Setting up the Java project and libraries
    2. Introducing the Wordz application
      1. Describing the rules of Wordz
    3. Exploring agile methods
      1. Reading user stories – the building block of planning
      2. Combining agile development with TDD
    4. Summary
    5. Questions and answers
    6. Further reading
  12. Chapter 5: Writing Our First Test
    1. Technical requirements
    2. Starting TDD: Arrange-Act-Assert
      1. Defining the test structure
      2. Working backward from outcomes
      3. Increasing workflow efficiency
    3. Defining a good test
      1. Applying the FIRST principles
      2. Using one assert per test
      3. Deciding on the scope of a unit test
    4. Catching common errors
    5. Asserting exceptions
    6. Only testing public methods
      1. Preserving encapsulation
    7. Learning from our tests
      1. A messy Arrange step
      2. A messy Act step
      3. A messy Assert step
      4. Limitations of unit tests
      5. Code coverage – an often-meaningless metric
      6. Writing the wrong tests
    8. Beginning Wordz
    9. Summary
    10. Questions and answers
  13. Chapter 6: Following the Rhythms of TDD
    1. Technical requirements
    2. Following the RGR cycle
      1. Starting on red
      2. Keep it simple – moving to green
      3. Refactoring to clean code
    3. Writing our next tests for Wordz
    4. Summary
    5. Questions and answers
    6. Further reading
  14. Chapter 7: Driving Design – TDD and SOLID
    1. Technical requirements
    2. Test guide – we drive the design
    3. SRP – simple building blocks
      1. Too many responsibilities make code harder to work with
      2. Ability to reuse code
      3. Simplified future maintenance
      4. Counter-example – shapes code that violates SRP
      5. Applying SRP to simplify future maintenance
      6. Organizing tests to have a single responsibility
    4. DIP – hiding irrelevant details
      1. Applying DI to the shapes code
    5. LSP – swappable objects
      1. Reviewing LSP usage in the shapes code
    6. OCP – extensible design
      1. Adding a new type of shape
    7. ISP – effective interfaces
      1. Reviewing ISP usage in the shapes code
    8. Summary
    9. Questions and answers
  15. Chapter 8: Test Doubles – Stubs and Mocks
    1. Technical requirements
    2. The problems collaborators present for testing
      1. The challenges of testing unrepeatable behavior
      2. The challenges of testing error handling
      3. Understanding why these collaborations are challenging
    3. The purpose of test doubles
      1. Making the production version of the code
    4. Using stubs for pre-canned results
      1. When to use stub objects
    5. Using mocks to verify interactions
    6. Understanding when test doubles are appropriate
      1. Avoiding the overuse of mock objects
      2. Don’t mock code you don’t own
      3. Don’t mock value objects
      4. You can’t mock without dependency injection
      5. Don’t test the mock
      6. When to use mock objects
    7. Working with Mockito – a popular mocking library
      1. Getting started with Mockito
      2. Writing a stub with Mockito
      3. Writing a mock with Mockito
      4. Blurring the distinction between stubs and mocks
      5. Argument matchers – customizing behavior of test doubles
    8. Driving error handling code with tests
    9. Testing an error condition in Wordz
    10. Summary
    11. Questions and answers
    12. Further reading
  16. Chapter 9: Hexagonal Architecture –Decoupling External Systems
    1. Technical requirements
    2. Why external systems are difficult
      1. Environmental problems bring trouble
      2. Accidentally triggering real transactions from tests
      3. What data should we expect?
      4. Operating system calls and system time
      5. Challenges with third-party services
    3. Dependency inversion to the rescue
      1. Generalizing this approach to the hexagonal architecture
      2. Overview of the hexagonal architecture’s components
      3. The golden rule – the domain never connects directly to adapters
      4. Why the hexagon shape?
    4. Abstracting out the external system
      1. Deciding what our domain model needs
    5. Writing the domain code
      1. Deciding what should be in our domain model
      2. Using libraries and frameworks in the domain model
      3. Deciding on a programming approach
    6. Substituting test doubles for external systems
      1. Replacing the adapters with test doubles
    7. Unit testing bigger units
      1. Unit testing entire user stories
    8. Wordz – abstracting the database
      1. Designing the repository interface
      2. Designing the database and random numbers adapters
    9. Summary
    10. Questions and answers
    11. Further reading
  17. Chapter 10: FIRST Tests and the Test Pyramid
    1. Technical requirements
    2. The test pyramid
    3. Unit tests – FIRST tests
    4. Integration tests
      1. What should an integration test cover?
      2. Testing database adapters
      3. Testing web services
      4. Consumer-driven contract testing
    5. End-to-end and user acceptance tests
      1. Acceptance testing tools
    6. CI/CD pipelines and test environments
      1. What is a CI/CD pipeline?
      2. Why do we need continuous integration?
      3. Why do we need continuous delivery?
      4. Continuous delivery or continuous deployment?
      5. Practical CI/CD pipelines
      6. Test environments
      7. Testing in production
    7. Wordz – integration test for our database
      1. Fetching a word from the database
    8. Summary
    9. Questions and answers
    10. Further reading
  18. Chapter 11: Exploring TDD with Quality Assurance
    1. TDD – its place in the bigger quality picture
      1. Understanding the limits of TDD
      2. No more need for manual testing?
    2. Manual exploratory – discovering the unexpected
    3. Code review and ensemble programming
    4. User interface and user experience testing
      1. Testing the user interface
      2. Evaluating the user experience
    5. Security testing and operations monitoring
    6. Incorporating manual elements into CI/CD workflows
    7. Summary
    8. Questions and answers
    9. Further reading
  19. Chapter 12: Test First, Test Later, Test Never
    1. Adding tests first
      1. Test-first is a design tool
      2. Tests form executable specifications
      3. Test-first provides meaningful code coverage metrics
      4. Beware of making a code coverage metric a target
      5. Beware of writing all tests upfront
      6. Writing tests first helps with continuous delivery
    2. We can always test it later, right?
      1. Test-later is easier for a beginner to TDD
      2. Test-later makes it harder to test every code path
      3. Test-later makes it harder to influence the software design
      4. Test-later may never happen
    3. Tests? They’re for people who can’t write code!
      1. What happens if we do not test during development?
    4. Testing from the inside out
    5. Testing from the outside in
    6. Defining test boundaries with hexagonal architecture
      1. Inside-out works well with the domain model
      2. Outside-in works well with adapters
      3. User stories can be tested across the domain model
    7. Summary
    8. Questions and answers
    9. Further reading
  20. Part 3: Real-World TDD
  21. Chapter 13: Driving the Domain Layer
    1. Technical requirements
    2. Starting a new game
      1. Test-driving starting a new game
      2. Tracking the progress of the game
      3. Triangulating word selection
    3. Playing the game
      1. Designing the scoring interface
      2. Triangulating game progress tracking
    4. Ending the game
      1. Responding to a correct guess
      2. Triangulating the game over due to too many incorrect guesses
      3. Triangulating response to guess after game over
      4. Reviewing our design
    5. Summary
    6. Questions and answers
    7. Further reading
  22. Chapter 14: Driving the Database Layer
    1. Technical requirements
      1. Installing the Postgres database
    2. Creating a database integration test
      1. Creating a database test with DBRider
      2. Driving out the production code
    3. Implementing the WordRepository adapter
      1. Accessing the database
      2. Implementing GameRepository
    4. Summary
    5. Questions and answers
    6. Further reading
  23. Chapter 15: Driving the Web Layer
    1. Technical requirements
    2. Starting a new game
      1. Adding required libraries to the project
      2. Writing the failing test
      3. Creating our HTTP server
      4. Adding routes to the HTTP server
      5. Connecting to the domain layer
      6. Refactoring the start game code
      7. Handling errors when starting a game
      8. Fixing the unexpectedly failing tests
    3. Playing the game
    4. Integrating the application
    5. Using the application
    6. Summary
    7. Questions and answers
    8. Further reading
  24. Index
    1. Why subscribe?
  25. Other Books You May Enjoy
    1. Packt is searching for authors like you
    2. Share Your Thoughts
    3. Download a free PDF copy of this book

Product information

  • Title: Test-Driven Development with Java
  • Author(s): Alan Mellor
  • Release date: January 2023
  • Publisher(s): Packt Publishing
  • ISBN: 9781803236230