### Question:
ResourceWatcher implements Destroyable { public void check(final CacheKey cacheKey) { check(cacheKey, new CallbackSupport()); }  void check(final CacheKey cacheKey); boolean tryAsyncCheck(final CacheKey cacheKey); void check(final CacheKey cacheKey, final Callback callback); void destroy();  }### Answer:
@Test(expected = NullPointerException.class) public void cannotCheckNullCacheEntry() { Context.unset(); victim.check(null); }
@Test public void shouldDetectChangeOfImportedResource() throws Exception { final String importResourceUri = "imported.css"; final CacheKey cacheEntry = new CacheKey(GROUP_NAME, ResourceType.CSS, true); victim = new ResourceWatcher(); createDefaultInjector().inject(victim); when(mockLocator.locate(Mockito.anyString())).thenAnswer(answerWithContent("initial")); when(mockLocator.locate("/" + Mockito.eq(RESOURCE_CSS_URI))).thenAnswer( answerWithContent(String.format("@import url(%s)", importResourceUri))); victim.check(cacheEntry, resourceWatcherCallback); when(mockLocator.locate(Mockito.anyString())).thenAnswer(answerWithContent("changed")); when(mockLocator.locate("/" + Mockito.eq(RESOURCE_CSS_URI))).thenAnswer( answerWithContent(String.format("@import url(%s)", importResourceUri))); victim.check(cacheEntry); verify(resourceWatcherCallback).onGroupChanged(Mockito.any(CacheKey.class)); verify(resourceWatcherCallback).onResourceChanged(Mockito.any(Resource.class)); }
@Test public void shouldNotDetectErroneouslyChange() throws Exception { createDefaultInjector().inject(victim); victim.check(cacheKey2, resourceWatcherCallback); when(mockLocator.locate(RESOURCE_JS_URI)).thenAnswer(answerWithContent("changed")); victim.check(cacheKey2, resourceWatcherCallback); verify(resourceWatcherCallback, Mockito.atLeastOnce()).onGroupChanged(Mockito.any(CacheKey.class)); verify(resourceWatcherCallback, Mockito.atLeastOnce()).onResourceChanged(Mockito.any(Resource.class)); Mockito.reset(resourceWatcherCallback); victim.check(cacheKey2, resourceWatcherCallback); verify(resourceWatcherCallback, Mockito.never()).onGroupChanged(Mockito.any(CacheKey.class)); verify(resourceWatcherCallback, Mockito.never()).onResourceChanged(Mockito.any(Resource.class)); }
@Test public void shouldInvokeCallbackWhenChangeIsDetected() throws Exception { final CallbackRegistryHolder callbackRegistryHolder = new CallbackRegistryHolder(); final AtomicBoolean flag = new AtomicBoolean(); final Injector injector = createDefaultInjector(); injector.inject(victim); injector.inject(callbackRegistryHolder); callbackRegistryHolder.registry.registerCallback(new ObjectFactory<LifecycleCallback>() { public LifecycleCallback create() { return new LifecycleCallbackSupport() { @Override public void onResourceChanged(final Resource resource) { flag.set(true); } }; } }); victim.check(cacheKey); assertTrue(flag.get()); }
@Test public void shouldRemoveKeyFromCacheStrategyWhenChangeDetected() { victim.check(cacheKey); final CacheValue cacheValue = null; verify(cacheStrategy).put(Mockito.eq(cacheKey), Mockito.eq(cacheValue)); }
@Test public void shouldCheckForResourceChangeAsynchronously() throws Exception { Context.get().getConfig().setResourceWatcherAsync(true); final CacheKey cacheKey1 = new CacheKey(MIXED_GROUP_NAME, ResourceType.CSS, true); final CacheKey cacheKey2 = new CacheKey(MIXED_GROUP_NAME, ResourceType.JS, true); victim.check(cacheKey1); victim.check(cacheKey2); when(mockLocator.locate(RESOURCE_JS_URI)).thenAnswer(answerWithContent("changed")); victim.check(cacheKey2, resourceWatcherCallback); verify(resourceWatcherCallback).onGroupChanged(Mockito.any(CacheKey.class)); verify(resourceWatcherCallback).onResourceChanged(Mockito.any(Resource.class)); }