SRP and Unit Testability in Java
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
SRP often improves testability because a test can exercise one concern without constructing unrelated parts of the application. If TaxPolicy.calculate(order) is a focused rule, a JUnit test can pass an Order and assert the amount without starting Spring, a database, or a mail server.
Persistence and notification adapters can then have their own integration or contract tests, while a use-case service tests the coordination between its required ports. Failures are easier to locate because each test has a narrower reason to fail.
This is not a numeric rule about mocks or setup lines. A focused orchestrator may legitimately have several collaborators, and @SpringBootTest is valuable for verifying real wiring. The design smell is unrelated setup needed to test one small policy, not the mere presence of integration tests.
SRP and Unit Testability in Java
Direct Answer
SRP can improve testing by isolating one policy from unrelated infrastructure and reducing irrelevant setup. A pricing rule can be tested with a small input instead of booting web, database, and mail components. This is a common benefit, not a guarantee: focused classes can still need collaborators, and integration tests remain necessary for wiring and real boundaries.
Code Example
final class TaxPolicy {
BigDecimal calculate(Order order) {
return order.subtotal().multiply(new BigDecimal("0.18"));
}
}
@Test
void calculatesTaxFromSubtotal() {
var policy = new TaxPolicy();
var order = new Order(new BigDecimal("100.00"));
assertEquals(new BigDecimal("18.0000"), policy.calculate(order));
}
The rule can be tested without an HTTP request, database, or mail client. Separate integration tests can verify those boundaries where they actually exist.
Common Mistakes & Pitfalls
- Treating fewer mocks as the definition of SRP: test setup is evidence, not a rule.
- Replacing every collaborator with a mock: simple values or fakes may express a contract more clearly.
- Calling every Spring integration test a design failure: use integration tests for wiring and real boundaries.
- Splitting without a cohesive responsibility: smaller classes are useful only when their purpose is clearer.
Check your understanding
Answer these without looking back at the article.
- How does Mockito benefit from SRP-compliant classes?
- What's the difference between a unit test and integration test?
- How does Spring DI relate to SRP?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.