### Question:
UpdatingSelfPopulatingCache extends SelfPopulatingCache { public Element get(final Object key) throws LockTimeoutException { try { Ehcache backingCache = getCache(); Element element = backingCache.get(key); if (element == null) { element = super.get(key); } else { Mutex lock = stripedMutex.getMutexForKey(key); try { lock.acquire(); update(key); } finally { lock.release(); } } return element; } catch (final Throwable throwable) { put(new Element(key, null)); throw new LockTimeoutException("Could not update object for cache entry with key \"" + key + "\".", throwable); } } UpdatingSelfPopulatingCache(Ehcache cache, final UpdatingCacheEntryFactory factory); Element get(final Object key); void refresh();  }### Answer:
@Test public void testFetchAndUpdate() throws Exception { final String value = "value"; final CountingCacheEntryFactory factory = new CountingCacheEntryFactory(value); selfPopulatingCache = new UpdatingSelfPopulatingCache(cache, factory); Element element = selfPopulatingCache.get(null); element = selfPopulatingCache.get("key"); assertSame(value, element.getObjectValue()); assertEquals(2, factory.getCount()); Object actualValue = selfPopulatingCache.get("key").getObjectValue(); assertSame(value, actualValue); assertEquals(3, factory.getCount()); actualValue = selfPopulatingCache.get("key").getObjectValue(); assertSame(value, actualValue); assertEquals(4, factory.getCount()); }
@Test public void testFetchFail() throws Exception { final Exception exception = new Exception("Failed."); final UpdatingCacheEntryFactory factory = new UpdatingCacheEntryFactory() { public Object createEntry(final Object key) throws Exception { throw exception; } public void updateEntryValue(Object key, Object value) throws Exception { throw exception; } }; selfPopulatingCache = new UpdatingSelfPopulatingCache(cache, factory); try { selfPopulatingCache.get("key"); fail(); } catch (final Exception e) { Thread.sleep(20); assertEquals("Could not update object for cache entry with key \"key\".", e.getMessage()); } }