我是编码和编程新手,我在 GitHub 上发现了一个有趣的使用 JavaScript 的 SimpleAgedCache 练习。我觉得我已经完成了正确的编码,并且练习应该通过测试。然而,测试一直失败。有人可以向我解释为什么会出现这种情况以及我做错了什么吗?谢谢。
package test.collective;
import io.collective.SimpleAgedCache;
import org.junit.Before;
import org.junit.Test;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import static junit.framework.TestCase.*;
class ExpirableEntry {
String key;
String value;
long expirationTime;
ExpirableEntry(String key, String value, long expirationTime) {
this.key = key;
this.value = value;
this.expirationTime = expirationTime;
}
}
public class SimpleAgedCacheTest {
private SimpleAgedCache empty;
private SimpleAgedCache nonempty;
private ExpirableEntry[] cacheArray;
private Clock clock;
private int size;
public SimpleAgedCacheTest() {
this.empty = new SimpleAgedCache();
this.nonempty = new SimpleAgedCache();
this.cacheArray = new ExpirableEntry[10];
this.clock = Clock.systemUTC();
this.size = 0;
}
public void put(String key, String value, long durationMillis) {
long expirationTime = clock.instant().plusMillis(durationMillis).toEpochMilli();
ExpirableEntry entry = new ExpirableEntry(key, value, expirationTime);
cacheArray[size++] = entry;
}
public String get(String key) {
for (int i = 0; i < size; i++) {
ExpirableEntry entry = cacheArray[i];
if (entry.key.equals(key) && !isExpired(entry)) {
return entry.value;
}
}
return null;
}
public boolean isEmpty() {
return size == 0;
}
public int size() {
return size;
}
private boolean isExpired(ExpirableEntry entry) {
return clock.instant().toEpochMilli() > entry.expirationTime;
}
@Before
public void setup() {
nonempty.put("aKey", "aValue", 2000);
nonempty.put("anotherKey", "anotherValue", 4000);
}
@Test
public void isEmptyTest() {
assertTrue(empty.isEmpty());
assertFalse(nonempty.isEmpty());
}
@Test
public void sizeTest() {
assertEquals(0, empty.size());
assertEquals(2, nonempty.size());
}
@Test
public void getTest() {
assertNull(empty.get("aKey"));
assertEquals("anotherValue", nonempty.get("anotherKey"));
assertEquals("aValue", nonempty.get("aKey"));
}
@Test
public void getExpiredTest() {
TestClock clock = new TestClock();
SimpleAgedCache expired = new SimpleAgedCache(clock);
expired.put("aKey", "aValue", 2000);
expired.put("anotherKey", "anotherValue", 4000);
clock.offset(Duration.ofMillis(3000));
assertEquals("anotherValue", expired.get("anotherKey"));
assertEquals(1, expired.size());
}
static class TestClock extends Clock {
Duration offset = Duration.ZERO;
@Override
public ZoneId getZone() {
return Clock.systemDefaultZone().getZone();
}
@Override
public Clock withZone(ZoneId zone) {
return Clock.offset(Clock.system(zone), offset);
}
@Override
public Instant instant() {
return Clock.offset(Clock.systemDefaultZone(), offset).instant();
}
public void offset(Duration offset) {
this.offset = offset;
}
}
}
我尝试过翻转
的顺序assertEquals("anotherValue", expired.get("anotherKey));
和
assertEquals(1, expired.size());
但没有效果。
@Test
public void getExpiredTest() {
TestClock clock = new TestClock();
SimpleAgedCache expired = new SimpleAgedCache(clock);
expired.put("aKey", "aValue", 2000);
expired.put("anotherKey", "anotherValue", 4000);
clock.offset(Duration.ofMillis(3000));
assertEquals("anotherValue", expired.get("anotherKey"));
assertEquals(1, expired.size());
您永远不会递减
size
,无论缓存数组保存的过期项目数量如何,该值始终会增加:
cacheArray[size++] = entry;
要解决此问题,您需要使
size()
计算具有条件 !isExpired(entry)
的条目数。