Your question is Refactor for Testability. Take a moment with it on the right.
Talk me through your thinking if you like. When you're confident, submit your answer and I'll grade it like a real screen (7/10 or better passes).
Noir Consulting's internal delivery team relies on a small Java utility to close out consultant timesheets at the end of each billing cycle. The class below computes the invoice amount, applies the standard discount, and writes a confirmation, but nobody on the team has ever been able to unit test it: every attempt ends up needing a live database and the real system clock.
public class TimesheetProcessor {
static List<String> AUDIT_LOG = new ArrayList<>();
public double closeTimesheet(String consultantId, double hoursWorked) throws SQLException {
DatabaseConnection db = new DatabaseConnection("jdbc:postgresql://prod-db:5432/billing");
double rate = db.getRateForConsultant(consultantId);
double total = hoursWorked * rate;
if (hoursWorked > 40) {
total = total * 0.85;
}
LocalDate closeDate = LocalDate.now();
AUDIT_LOG.add(consultantId + " closed on " + closeDate);
db.writeInvoice(consultantId, total);
System.out.println("Invoice for " + consultantId + ": " + total);
EmailService.send(consultantId + "@noirconsulting.com", "Your timesheet has been closed.");
return total;
}
}
Explain, in plain text, everything about this class that makes it resistant to unit testing, and what you would change so it could be tested without a live database, a real clock, or a real mailbox.