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