When stubbing methods couples tests to implementation, extract an interface (e.g. `Dice`) and dependency-inject an implementation. Production code passes the real class; tests pass a fake whose outputs are scripted. Benefits: code stays open for extension, tests remain deterministic, refactoring is easier. Costs: more code in tests, the fake must be kept in sync with the real class, and picking the wrong abstraction early makes future change expensive.