Test isolation means that one test’s result does not depend on state or execution effects from other tests. A mutable global time function breaks this property: tests share state and cannot safely run in parallel. section 11.6
Replace shared time with an injected dependency
A Cache that stores a now function can default to time.Now in production while tests provide a fixed timestamp. The test then uses deterministic event times and no shared mutable clock. Passing the current time as a method argument is simpler, but gives callers more responsibility and is less extensible when additional time operations are needed. 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
}
}
}
Trace where direct time.Now enters cache trimming, then compare it with a test that supplies a fixed clock. section 11.6


