Calling time.Now() inside time-sensitive logic can make unit tests brittle: machine load may change which events a duration-based cache removes. Treat the clock as a dependency when deterministic tests matter. section 11.6
type Cache struct {
mu sync.RWMutex
events []Event
}
type Event struct {
Timestamp time.Time
Data string
}
func (c *Cache) TrimOlderThan(since time.Duration) {
c.mu.RLock()
defer c.mu.RUnlock()
t := time.Now().Add(-since) #1
for i := 0; i < len(c.events); i++ {
if c.events[i].Timestamp.After(t) {
c.events = c.events[i:] #2
return
}
}
}
The cache computes a cutoff with time.Now().Add(-since), then removes older events from its time-sorted slice. section 11.6
Replace the live clock in tests
Define a now func() time.Time field, initialize it with time.Now in NewCache, and override it with a fixed timestamp in tests. Events at 04, 05, and 06 seconds with a fixed current time of 06 seconds make a 15-millisecond trim deterministic. Alternatives include passing the current time to TrimOlderThan or storing time.Now in a replaceable package variable; choose the boundary that best fits the design. section 11.6 section 11.10
