Repeated setup makes tests hard to scan and expensive to update. A factory function centralizes creation: it returns a new object, fake dependency, or preconfigured function so callers state the scenario they need instead of repeating construction details. section 8.1.2 section 2.7
For example, a verifier factory can create a PasswordVerifier with a default fake logger. If its constructor later changes, update the factory rather than every test that instantiated it directly. Factories therefore hide creation details while leaving each test focused on its inputs and expectations. section 8.1.2 section 3.7.1
Create a configured verifier
const makeVerifier = (rules, dayOfWeekFn) => { return (input) => { if ([0, 6].includes(dayOfWeekFn())) { throw new Error("It's the weekend!"); } }; }; const alwaysSunday = () => 0; const verifyPassword = makeVerifier([], alwaysSunday); The factory receives rules and a time dependency once, then returns a verifier that needs only input. This higher-order form bakes configuration into the returned function's closure. section 3.4.2 section 4.6.2
Use a factory when it improves the test's story:
- Create passing or failing rules with small helpers when the same test states recur. section 2.7
- Call a factory inside each test when nested beforeEach() blocks make object creation hard to find; this keeps state local and reduces scroll fatigue. section 2.7.1 section 2.12
- Keep separate factories for objects such as verifiers and fake loggers when API changes would otherwise break many tests. section 8.1.2
- Prefer a custom factory over framework wiring when direct construction and explicit fake dependencies are easier to read and reason about. section 3.7.2
A factory used by production code can provide a real default dependency, while a test factory usually exists only to make setup maintainable. A factory that returns a configured function is also different from a helper that returns an object instance, though both centralize creation. section 3.7.1 section 3.4.2 section 3.7.2










