SlideShare a Scribd company logo
Your tests are trying
to tell you something
by Victor Rentea at
9 design hints you were missing
Read the article:
https://victorrentea.ro/blog/design-insights-from-unit-testing/
Get the code:
https://github.com/victorrentea/unit-testing.git Branch: 9hints_talk
victorrentea.ro
Hi, I'm Victor Rentea
Java Champion – drinking since 2006
Trainer – 3000+ devs in 80+ companies
Speaker – Conferences & Meetups
Hibernate
Spring Advanced FP
Java Performance Secure Coding
Reactive
Architecture Clean Code Unit Testing
pro
Hibernate
Spring Advanced FP
Architecture Clean Code Unit Testing
Masterclass
Company
Training
Video
Lessons
@victorrentea
VictorRentea.ro
victorrentea@gmail.com
Java Performance Secure Coding
Reactive
victorrentea.ro/community
Join My
Community
YouTube
Channel
youtube.com/user/vrentea
335 © VictorRentea.ro
a training by
&
(referring to an old Romanian saying)
- NO COMMENT -
336 © VictorRentea.ro
a training by
▪Better Signatures ⌨= code
▪Immutable Objects ⌨
▪CQS Principle ⌨
▪Functional Core / Imperative Shell ⌨
▪Separation by Layers of Abstraction ⌨
▪Decouple Unrelated Complexity ⌨
▪Role-based Design
▪Onion Architecture
▪Breakdown Data Objects ⌨
Design Improvements hinted by Unit Tests
337 © VictorRentea.ro
a training by
Are you agile?
"Emergent Architecture"
Ever heard of the
338 © VictorRentea.ro
a training by
Are you agile?
Tests give you hints
on how to break
and design complex logic
"Emergent Architecture"
that never emerges 
Under-design is the default today?
339 © VictorRentea.ro
a training by
Do you write Tests
BEFORE the implementation?
Writing #responsible Unit Tests will 🚀 YOUR design skills
If you would, you'd get
✔ more real coverage => courage
✔ more early design feedback
The point of this talk
→ Mocks
340 © VictorRentea.ro
a training by
Mocks make our tests...
Repeatable
isolated from external systems
Fast ✔
DB, external APIs
Reasonably Complex ✔
When facing high cyclomatic complexity ➔
Alternatives:
in-memory DB (H2)
Testcontainers
WireMock
341 © VictorRentea.ro
a training by
Logic
to test
Cyclomatic Complexity
= number of independent paths through code
Test
Test
Test
Test
Test
Test
Test
CC=5 CC=6
f(a) g(b)
calls
CC=30
Too Many
To cover all branches
Too Heavy
in setup and input data (a and b)
End-to-end tests grow...
342 © VictorRentea.ro
a training by
⛔
If there's not much complexity,
avoid mocks
A B
Instead,
test clusters of objects
Internal refactoring
won't break tests 👍
343 © VictorRentea.ro
a training by
(The rest of the talk assumes we have serious complexity)
Unit Testing intensifies design
around complex logic
344 © VictorRentea.ro
a training by
345 © VictorRentea.ro
a training by
Precise Signatures
Methods taking less data as arguments are easier to understand; ✔
and less coupled
method(heavyObject)
HeavyObject having dozens of fields
method(part1, part2)
only takes necessary parts of HeavyObject
Tests will get simpler
new HeavyObject(..)
346 © VictorRentea.ro
a training by
Immutable Objects ✔
eg. Mutating a parameter often causes awkward bugs.
method(obj) {
obj.setX(..);
}
method(..) {
return x;
}
when(b.method(..)).thenReturn("stub");
doAnswer(invocation -> .. obj.setX("stub"))
.when(b).method(any());
Mocking such a method is painful:
347 © VictorRentea.ro
a training by
do side-effects
return void sendEmail(Email):void
Command-Query Separation
setActive(true):void
return results
search(criteria):List
computePrice(flight):int
Bertrand Meyer, in 1994:
Pure Functions
348 © VictorRentea.ro
a training by
No side effects
(doesn't change anything)
No INSERTs, POSTs, queues, files, NO Fields changed,…
𝑒𝑔: 𝑀𝑎𝑡ℎ𝑒𝑚𝑎𝑡𝑖𝑐𝑎𝑙 𝐹𝑢𝑛𝑐𝑡𝑖𝑜𝑛𝑠: 𝑓 𝑥, 𝑦 = 𝑥2
+ 𝑦
+
Referential Transparent
(same inputs produce the same output)
No current time, random, GET, SELECT…
Pure Functions
349 © VictorRentea.ro
a training by
Command-Query Separation Principle
A method should be either
a query (pure function, returning data), or
a command (side-effecting, returning void)
If you need to both stub (when...) and verify the same method,
you are breaking CQS:
Exception: external calls should happen ONCE
eg. REST/WSDL calls that are critical, cost money, or take time
when(b.query(..)).thenReturn(X);
prod.call();
verify(b).command(Y);
when(b.god(..)).thenReturn(X);
prod.call();
verify(b).god(Y);
Apply inside core logic
https://martinfowler.com/articles/mocksArentStubs.html
350 © VictorRentea.ro
a training by
Functional Core / Imperative Shell Segregation
The heavier some logic is, the less dependencies it should have.
Keep complex logic in pure functions. ✔
Complex logic requires many tests.
Shrink these tests by limiting mocks.
=> loose coupling
when.thenReturn(..);
when.thenReturn(..);
when.thenReturn(x);
when.thenReturn(y);
prod.complex();
verify(..).f(z);
verify(..).g();
verify(..).h();
x7=😖
when.thenReturn(..); // ideally 0 mocks
z = prod.complex(x, y);
assert..(z...);
351 © VictorRentea.ro
a training by
Dependencies
Heavy complexity
Side-effects
FUNCTIONAL CORE
PURE
FUNCTION
352 © VictorRentea.ro
a training by
Design the Most Complex Parts of Logic
as Pure Functions 💘
Easier to Understand Easier to Test
353 © VictorRentea.ro
a training by
Separation by Layers of Abstraction
You have two complex functions in the same class, f() calling g()
Move g() in a separate class ✔
You test g() separately.
When testing f(), you don't want it to call g(), as g was tested
Using partial mocks (@Spy) leads to horrid tests. Solution:
class Big {
f() {
//complex
g();
}
g() {
//complex
}
}
class HighLevel {
LowLevel low;
f() {
//complex
low.g();
}
}
class LowLevel {
g() {
//complex
}
}
354 © VictorRentea.ro
a training by
▪Better Signatures
▪Immutable Objects
▪CQS Principle
▪Functional Core / Imperative Shell
▪Separation by Layers of Abstraction
▪Decouple Unrelated Complexity
▪Role-based Design
▪Onion Architecture
▪Breakdown Data Objects
Design Improvements hinted by Unit Tests
355 © VictorRentea.ro
a training by
Fixture Creep
2 complex functions in the same class, use different sets of dependencies.
Break unrelated complexity for clarity and loose coupling. ✔
// prod code
class Wide {
A a;
B b;
complex1() {
//uses a
}
complex2() {
//uses b
}
}
class WideTest {
@Mock A a;
@Mock B b;
@InjectMocks Wide wide;
@BeforeEach
init() {//shared fixture
when(a..).then
when(b..).then
}
// 5 tests for complex1
// 4 tests for complex2
}
class Complex1Test {
@Mock A a;
@Mock B b;
}
class Complex2Test {
@Mock B b;
@Mock C c;
}
Testing both in the same Test class leads to a
bloated fixture ("Before").
Hard to trace later what's used by one test.
Break the test class.
Also: Hierarchical Tests.
356 © VictorRentea.ro
a training by
Mock Roles, not Objects
Bad Habit: You finish the implementation, then you write tests.
You [blindly] @Mock all dependencies.
Two years later, your tests are fragile and slow you down.
Before mocking a dependency, clarify its role. ✔
And test earlier.
http://jmock.org/oopsla2004.pdf
357 © VictorRentea.ro
a training by
Problem: You allow external APIs, DTOs, and ugly frameworks
to enter freely in your core logic.
Testing your core logic now requires creating foreign objects,
or mocking an awkward library.
Onion Architecture
Pull core logic in an Agnostic Domain ✔
So most tests talk in terms of your internal Domain Model ✔
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
application
Value Object
Entity
id
Domain
Service
Domain
Service
(agnostic)
domain
DTO
External
API
DTO
UI,
Client
External
Systems
Façade
Controller
IRepo
Clean Pragmatic Architecture
at Devoxx Ukraine 2021
Curious for more?
↓
IAdapter
Adapter
⛔
⛔
359 © VictorRentea.ro
a training by
Creepy Object Mother
You use large data structures in your core logic.
If the structures enforce their internal consistency,
(it's not an anemic model only having getters and setters)
then creating test data instances becomes cumbersome,
(unrelated fields to set)
so you share a global "TestData" class that builds correct instances.
TestData gets bloated and couples your tests together.
Break TestData🪓 in several classes
Break data structures🪓 in separate Bounded Contexts?
ie packages>modular monolith>microservices🤞
https://martinfowler.com/bliki/ObjectMother.html (2006)
360 © VictorRentea.ro
a training by
Unit testing - 9 design hints
362 © VictorRentea.ro
a training by
▪More Calls from Tests > Better Signatures, Better Skills
▪Immutable Objects 🤘 (rock)
▪when.then xor verify > Command-Query Separation
▪More Tests ➔ ↓Mocks > Functional Core / Imperative Shell
▪Partial Mocks > Separation by Layers of Abstraction
▪Bloated Fixture > Break Test > Decouple Unrelated Complexity
▪Mock Roles not Objects > Role-based Design
▪Keep most tests on Domain > Onion Architecture
▪Creepy Object Mother > Break Data Objects
> 2 Bounded Contexts?
Recap
363 © VictorRentea.ro
a training by

More Related Content

PDF
Stable Diffusion path
PDF
Vectors are the new JSON in PostgreSQL (SCaLE 21x)
PDF
Manage Microservices Chaos and Complexity with Observability
PDF
Kotlin界のsealed classはJava界でも『sealed』なのか
PDF
Single Image Super Resolution Overview
PDF
Mini-Training: Netflix Simian Army
PDF
Self-supervised Learning Lecture Note
PPTX
Anomaly detection, part 1
Stable Diffusion path
Vectors are the new JSON in PostgreSQL (SCaLE 21x)
Manage Microservices Chaos and Complexity with Observability
Kotlin界のsealed classはJava界でも『sealed』なのか
Single Image Super Resolution Overview
Mini-Training: Netflix Simian Army
Self-supervised Learning Lecture Note
Anomaly detection, part 1

Similar to Unit testing - 9 design hints (20)

PPTX
Test-Driven Design Insights@DevoxxBE 2023.pptx
PPTX
The tests are trying to tell you something@VoxxedBucharest.pptx
PDF
Don't Be Mocked by your Mocks - Best Practices using Mocks
PDF
Pure functions and immutable objects @dev nexus 2021
PDF
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021
PDF
Testing Microservices @DevoxxBE 23.pdf
PDF
Unit Testing like a Pro - The Circle of Purity
PDF
Pure Functions and Immutable Objects
PDF
The Proxy Fairy, and The Magic of Spring Framework
PDF
The Art of Unit Testing - Towards a Testable Design
PDF
How and what to unit test
ODP
PHP Barcelona 2010 - Architecture and testability
PDF
Neal Ford Emergent Design And Evolutionary Architecture
PDF
Integration testing with spring @JAX Mainz
PDF
Clean architecture - Protecting the Domain
PPTX
Python mocking intro
PDF
Troubleshooting tips from docker support engineers
PDF
Modern Python Testing
KEY
Javascript unit testing, yes we can e big
PDF
Clean pragmatic architecture @ devflix
Test-Driven Design Insights@DevoxxBE 2023.pptx
The tests are trying to tell you something@VoxxedBucharest.pptx
Don't Be Mocked by your Mocks - Best Practices using Mocks
Pure functions and immutable objects @dev nexus 2021
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021
Testing Microservices @DevoxxBE 23.pdf
Unit Testing like a Pro - The Circle of Purity
Pure Functions and Immutable Objects
The Proxy Fairy, and The Magic of Spring Framework
The Art of Unit Testing - Towards a Testable Design
How and what to unit test
PHP Barcelona 2010 - Architecture and testability
Neal Ford Emergent Design And Evolutionary Architecture
Integration testing with spring @JAX Mainz
Clean architecture - Protecting the Domain
Python mocking intro
Troubleshooting tips from docker support engineers
Modern Python Testing
Javascript unit testing, yes we can e big
Clean pragmatic architecture @ devflix
Ad

More from Victor Rentea (20)

PDF
Top REST API Desgin Pitfalls @ Devoxx 2024
PDF
The Joy of Testing - Deep Dive @ Devoxx Belgium 2024
PDF
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
PDF
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
PDF
Microservice Resilience Patterns @VoxxedCern'24
PDF
Distributed Consistency.pdf
PDF
Clean Code @Voxxed Days Cluj 2023 - opening Keynote
PPTX
From Web to Flux @DevoxxBE 2023.pptx
PDF
Profiling your Java Application
PPTX
OAuth in the Wild
PPTX
Vertical Slicing Architectures
PDF
Software Craftsmanship @Code Camp Festival 2022.pdf
PPTX
Extreme Professionalism - Software Craftsmanship
PDF
Refactoring blockers and code smells @jNation 2021
PDF
Hibernate and Spring - Unleash the Magic
PDF
Integration testing with spring @snow one
PDF
TDD Mantra
PDF
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
PDF
Definitive Guide to Working With Exceptions in Java
PDF
Extreme Professionalism - Software Craftsmanship
Top REST API Desgin Pitfalls @ Devoxx 2024
The Joy of Testing - Deep Dive @ Devoxx Belgium 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Microservice Resilience Patterns @VoxxedCern'24
Distributed Consistency.pdf
Clean Code @Voxxed Days Cluj 2023 - opening Keynote
From Web to Flux @DevoxxBE 2023.pptx
Profiling your Java Application
OAuth in the Wild
Vertical Slicing Architectures
Software Craftsmanship @Code Camp Festival 2022.pdf
Extreme Professionalism - Software Craftsmanship
Refactoring blockers and code smells @jNation 2021
Hibernate and Spring - Unleash the Magic
Integration testing with spring @snow one
TDD Mantra
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
Definitive Guide to Working With Exceptions in Java
Extreme Professionalism - Software Craftsmanship
Ad

Recently uploaded (20)

PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
System and Network Administraation Chapter 3
PPTX
ai tools demonstartion for schools and inter college
PDF
Nekopoi APK 2025 free lastest update
PPTX
CHAPTER 2 - PM Management and IT Context
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
System and Network Administration Chapter 2
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PDF
Understanding Forklifts - TECH EHS Solution
How Creative Agencies Leverage Project Management Software.pdf
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Odoo Companies in India – Driving Business Transformation.pdf
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
System and Network Administraation Chapter 3
ai tools demonstartion for schools and inter college
Nekopoi APK 2025 free lastest update
CHAPTER 2 - PM Management and IT Context
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Internet Downloader Manager (IDM) Crack 6.42 Build 41
2025 Textile ERP Trends: SAP, Odoo & Oracle
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Navsoft: AI-Powered Business Solutions & Custom Software Development
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
Wondershare Filmora 15 Crack With Activation Key [2025
System and Network Administration Chapter 2
VVF-Customer-Presentation2025-Ver1.9.pptx
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Understanding Forklifts - TECH EHS Solution

Unit testing - 9 design hints

  • 1. Your tests are trying to tell you something by Victor Rentea at 9 design hints you were missing Read the article: https://victorrentea.ro/blog/design-insights-from-unit-testing/ Get the code: https://github.com/victorrentea/unit-testing.git Branch: 9hints_talk victorrentea.ro
  • 2. Hi, I'm Victor Rentea Java Champion – drinking since 2006 Trainer – 3000+ devs in 80+ companies Speaker – Conferences & Meetups Hibernate Spring Advanced FP Java Performance Secure Coding Reactive Architecture Clean Code Unit Testing
  • 3. pro Hibernate Spring Advanced FP Architecture Clean Code Unit Testing Masterclass Company Training Video Lessons @victorrentea VictorRentea.ro victorrentea@gmail.com Java Performance Secure Coding Reactive victorrentea.ro/community Join My Community YouTube Channel youtube.com/user/vrentea
  • 4. 335 © VictorRentea.ro a training by & (referring to an old Romanian saying) - NO COMMENT -
  • 5. 336 © VictorRentea.ro a training by ▪Better Signatures ⌨= code ▪Immutable Objects ⌨ ▪CQS Principle ⌨ ▪Functional Core / Imperative Shell ⌨ ▪Separation by Layers of Abstraction ⌨ ▪Decouple Unrelated Complexity ⌨ ▪Role-based Design ▪Onion Architecture ▪Breakdown Data Objects ⌨ Design Improvements hinted by Unit Tests
  • 6. 337 © VictorRentea.ro a training by Are you agile? "Emergent Architecture" Ever heard of the
  • 7. 338 © VictorRentea.ro a training by Are you agile? Tests give you hints on how to break and design complex logic "Emergent Architecture" that never emerges  Under-design is the default today?
  • 8. 339 © VictorRentea.ro a training by Do you write Tests BEFORE the implementation? Writing #responsible Unit Tests will 🚀 YOUR design skills If you would, you'd get ✔ more real coverage => courage ✔ more early design feedback The point of this talk → Mocks
  • 9. 340 © VictorRentea.ro a training by Mocks make our tests... Repeatable isolated from external systems Fast ✔ DB, external APIs Reasonably Complex ✔ When facing high cyclomatic complexity ➔ Alternatives: in-memory DB (H2) Testcontainers WireMock
  • 10. 341 © VictorRentea.ro a training by Logic to test Cyclomatic Complexity = number of independent paths through code Test Test Test Test Test Test Test CC=5 CC=6 f(a) g(b) calls CC=30 Too Many To cover all branches Too Heavy in setup and input data (a and b) End-to-end tests grow...
  • 11. 342 © VictorRentea.ro a training by ⛔ If there's not much complexity, avoid mocks A B Instead, test clusters of objects Internal refactoring won't break tests 👍
  • 12. 343 © VictorRentea.ro a training by (The rest of the talk assumes we have serious complexity) Unit Testing intensifies design around complex logic
  • 14. 345 © VictorRentea.ro a training by Precise Signatures Methods taking less data as arguments are easier to understand; ✔ and less coupled method(heavyObject) HeavyObject having dozens of fields method(part1, part2) only takes necessary parts of HeavyObject Tests will get simpler new HeavyObject(..)
  • 15. 346 © VictorRentea.ro a training by Immutable Objects ✔ eg. Mutating a parameter often causes awkward bugs. method(obj) { obj.setX(..); } method(..) { return x; } when(b.method(..)).thenReturn("stub"); doAnswer(invocation -> .. obj.setX("stub")) .when(b).method(any()); Mocking such a method is painful:
  • 16. 347 © VictorRentea.ro a training by do side-effects return void sendEmail(Email):void Command-Query Separation setActive(true):void return results search(criteria):List computePrice(flight):int Bertrand Meyer, in 1994: Pure Functions
  • 17. 348 © VictorRentea.ro a training by No side effects (doesn't change anything) No INSERTs, POSTs, queues, files, NO Fields changed,… 𝑒𝑔: 𝑀𝑎𝑡ℎ𝑒𝑚𝑎𝑡𝑖𝑐𝑎𝑙 𝐹𝑢𝑛𝑐𝑡𝑖𝑜𝑛𝑠: 𝑓 𝑥, 𝑦 = 𝑥2 + 𝑦 + Referential Transparent (same inputs produce the same output) No current time, random, GET, SELECT… Pure Functions
  • 18. 349 © VictorRentea.ro a training by Command-Query Separation Principle A method should be either a query (pure function, returning data), or a command (side-effecting, returning void) If you need to both stub (when...) and verify the same method, you are breaking CQS: Exception: external calls should happen ONCE eg. REST/WSDL calls that are critical, cost money, or take time when(b.query(..)).thenReturn(X); prod.call(); verify(b).command(Y); when(b.god(..)).thenReturn(X); prod.call(); verify(b).god(Y); Apply inside core logic https://martinfowler.com/articles/mocksArentStubs.html
  • 19. 350 © VictorRentea.ro a training by Functional Core / Imperative Shell Segregation The heavier some logic is, the less dependencies it should have. Keep complex logic in pure functions. ✔ Complex logic requires many tests. Shrink these tests by limiting mocks. => loose coupling when.thenReturn(..); when.thenReturn(..); when.thenReturn(x); when.thenReturn(y); prod.complex(); verify(..).f(z); verify(..).g(); verify(..).h(); x7=😖 when.thenReturn(..); // ideally 0 mocks z = prod.complex(x, y); assert..(z...);
  • 20. 351 © VictorRentea.ro a training by Dependencies Heavy complexity Side-effects FUNCTIONAL CORE PURE FUNCTION
  • 21. 352 © VictorRentea.ro a training by Design the Most Complex Parts of Logic as Pure Functions 💘 Easier to Understand Easier to Test
  • 22. 353 © VictorRentea.ro a training by Separation by Layers of Abstraction You have two complex functions in the same class, f() calling g() Move g() in a separate class ✔ You test g() separately. When testing f(), you don't want it to call g(), as g was tested Using partial mocks (@Spy) leads to horrid tests. Solution: class Big { f() { //complex g(); } g() { //complex } } class HighLevel { LowLevel low; f() { //complex low.g(); } } class LowLevel { g() { //complex } }
  • 23. 354 © VictorRentea.ro a training by ▪Better Signatures ▪Immutable Objects ▪CQS Principle ▪Functional Core / Imperative Shell ▪Separation by Layers of Abstraction ▪Decouple Unrelated Complexity ▪Role-based Design ▪Onion Architecture ▪Breakdown Data Objects Design Improvements hinted by Unit Tests
  • 24. 355 © VictorRentea.ro a training by Fixture Creep 2 complex functions in the same class, use different sets of dependencies. Break unrelated complexity for clarity and loose coupling. ✔ // prod code class Wide { A a; B b; complex1() { //uses a } complex2() { //uses b } } class WideTest { @Mock A a; @Mock B b; @InjectMocks Wide wide; @BeforeEach init() {//shared fixture when(a..).then when(b..).then } // 5 tests for complex1 // 4 tests for complex2 } class Complex1Test { @Mock A a; @Mock B b; } class Complex2Test { @Mock B b; @Mock C c; } Testing both in the same Test class leads to a bloated fixture ("Before"). Hard to trace later what's used by one test. Break the test class. Also: Hierarchical Tests.
  • 25. 356 © VictorRentea.ro a training by Mock Roles, not Objects Bad Habit: You finish the implementation, then you write tests. You [blindly] @Mock all dependencies. Two years later, your tests are fragile and slow you down. Before mocking a dependency, clarify its role. ✔ And test earlier. http://jmock.org/oopsla2004.pdf
  • 26. 357 © VictorRentea.ro a training by Problem: You allow external APIs, DTOs, and ugly frameworks to enter freely in your core logic. Testing your core logic now requires creating foreign objects, or mocking an awkward library. Onion Architecture Pull core logic in an Agnostic Domain ✔ So most tests talk in terms of your internal Domain Model ✔ https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
  • 28. 359 © VictorRentea.ro a training by Creepy Object Mother You use large data structures in your core logic. If the structures enforce their internal consistency, (it's not an anemic model only having getters and setters) then creating test data instances becomes cumbersome, (unrelated fields to set) so you share a global "TestData" class that builds correct instances. TestData gets bloated and couples your tests together. Break TestData🪓 in several classes Break data structures🪓 in separate Bounded Contexts? ie packages>modular monolith>microservices🤞 https://martinfowler.com/bliki/ObjectMother.html (2006)
  • 31. 362 © VictorRentea.ro a training by ▪More Calls from Tests > Better Signatures, Better Skills ▪Immutable Objects 🤘 (rock) ▪when.then xor verify > Command-Query Separation ▪More Tests ➔ ↓Mocks > Functional Core / Imperative Shell ▪Partial Mocks > Separation by Layers of Abstraction ▪Bloated Fixture > Break Test > Decouple Unrelated Complexity ▪Mock Roles not Objects > Role-based Design ▪Keep most tests on Domain > Onion Architecture ▪Creepy Object Mother > Break Data Objects > 2 Bounded Contexts? Recap