Why does testing a business rule need a database?
Separate who qualifies for a reminder from whether the reminder can be delivered.
One account expired yesterday; another expires tomorrow. Why should checking who gets a reminder require an email service?
Put the inputs on the table
Bernhardt moves the decision into a function. The outer code reads records, supplies them to the function and sends the resulting messages. Two records and a date are enough to test the rule. A separate integration check verifies that the database actually supplies those records.
the expired users class makes all the decisions and the sweeper class has all the dependencies.Replay 15:28–15:38 →
Midnight is an input too
Hickey suggests checking whether identical inputs produce identical outputs. A function that secretly reads the clock can disagree with itself across midnight. Pass the date explicitly and you can replay the decision.
a true functional interface, same input, same output.Replay 37:13–37:21 →
When a small test needs several mocks, list the values the decision actually needs. Then test separately how the running system obtains those values.