I have an interface called localcache:
package localcache
type Cache interface {
Set(k string, v interface{}) error
Get(k string) (interface{}, error)
}
and another file containing its implementation
type cache struct {
pool map[string]value
}
type value struct {
data interface{}
expiredAt time.Time
}
func New() *cache {
if cacheInstance == nil {
once.Do(func() {
cacheInstance = &cache{
pool: make(map[string]value),
}
go cacheInstance.spawnCacheChcker()
})
return cacheInstance
}
return cacheInstance
}
func (c *cache) Set(k string, v interface{}) (e error) {
expiredAt := time.Now().Add(expiredIn)
c.pool[k] = value{data: v, expiredAt: expiredAt}
e = nil
return
}
func (c *cache) Get(k string) (v interface{}, e error) {
v = c.pool[k].data
e = nil
return
}
func (c *cache) spawnCacheChcker() {
for {
for k, v := range c.pool {
if !(v.expiredAt.Before(time.Now())) {
continue
}
c.evictCache(k)
}
time.Sleep(checkInBetween)
}
}
a cache will be expired 30 seconds after it's been set, how can I test this functionality? I'm using testify rn, my brute force solution was to time.Sleep in the test function, but I feel like this will prolong the entire test process, which is not the best practice.
Is there any ways to mock the expiredAt
inside the Set function? Or is there any workaround that tests this better?
You can move
time.Now()
to be a field in cache struct likethen assign time.Now to it in the constructor. Within the test, just modify it to your mock function to return any time you want.