ADR-0002: Sociable Unit Tests¶
Status¶
Accepted
Context¶
Unit tests can follow two strategies:
Solitary tests: Each class is tested in isolation with all collaborators replaced by mocks/stubs.
Sociable tests: Tests exercise a class together with its real collaborators, mocking only external dependencies.
Excessive mocking leads to brittle tests that break on refactoring even when behavior is preserved. Mocks also hide integration issues that only surface in production.
Decision¶
Use sociable unit tests as the default testing strategy:
Test with real collaborators whenever possible
Use mocks only for external dependencies: database, network, filesystem
Run tests with
python -m unittest(never pytest)
import unittest
class TestOrderService(unittest.TestCase):
def test_create_order(self):
# Real collaborators, no mocks
repository = InMemoryOrderRepository()
service = OrderService(repository)
order = service.create_order(customer_id=1, items=['item1'])
self.assertEqual(order.customer_id, 1)
Consequences¶
Tests exercise real interaction paths, catching integration issues early
Refactoring internal collaborators does not break tests if behavior is preserved
Test setup may be more involved (constructing real collaborator graphs)
External dependencies still need mocks/stubs for determinism and speed