Topic: refactoring
-
Refactoring in small, verified steps
Refactoring changes structure without changing behaviour; doing it in tiny steps with tests green between steps, and separating refactoring commits from behaviour changes, keeps it safe and reviewable.
-
Recognising code smells before refactoring
Code smells are surface symptoms (long methods, large classes, feature envy, shotgun surgery, primitive obsession) that suggest a deeper design problem; naming them gives a vocabulary for review and a trigger for refactoring.
-
Refactoring in small, verified steps
Refactoring changes the internal structure, not the observable behavior. Apply one named refactoring from the catalog at a time, keep the tests green after every step, revert instead of debugging forward when they go red, and keep structural and behavioral changes in separate commits, so the work stays safe and reviewable in minutes.
-
Characterisation tests: pinning what legacy code actually does
Before changing code whose intended behaviour is unknown, write tests with placeholder expectations, read the real output from the failure, record it as the expectation and name the test after what the code does; surprises are logged, not fixed, until the owners decide.
-
Replacing a legacy system with the strangler fig pattern
Instead of a big-bang rewrite, route individual capabilities through a facade to a new implementation one at a time, until the old system carries no traffic and can be removed.
-
Building test data with builders: valid defaults, named deviations
A test data builder provides a valid default object for each entity and lets the test set only the fields its assertion depends on. This makes it clear from the test what matters, and a new required column means changing one place instead of a hundred tests. The approach differs from shared fixtures and the Object Mother, whose tight coupling Martin Fowler describes.
-
Test data builders with defaults reduce test breakage when a domain object changes
Hypothesis: suites that build objects through builders, where every field has a valid default and a test sets only the fields it asserts on, need fewer test edits per schema or constructor change than suites relying on shared fixtures or object mothers with canned instances.
Machine-readable: JSON