public void setUp(final Object testService) {
    MockitoAnnotations.initMocks(this);
    when(cache.getName()).thenReturn(AnnotationConstants.DEFAULT_CACHE_NAME);
    when(cache.getProperties()).thenReturn(new CacheProperties());
    advice = createAdvice();
    CacheBase cacheBase = new CacheBase();
    cacheBase.addCache(cache);
    advice.setCacheBase(cacheBase);

    when(signature.getName()).thenReturn(methodName);
    when(signature.getParameterTypes()).thenReturn(paramTypes);
    when(pjp.getSignature()).thenReturn(signature);
    when(pjp.toShortString()).thenReturn(methodName);
    when(pjp.getArgs()).thenReturn(params);

    when(signature.getDeclaringType()).thenReturn(testService.getClass());
    when(pjp.getTarget()).thenReturn(testService);

    if (isValid && cacheKey == null) {
      cacheKey = getKey(getNamespace(), params);
    }
  }
  private void doUpdate(final JoinPoint jp, final Object retVal) throws Throwable {
    if (isCacheDisabled()) {
      LOG.debug("Caching is disabled.");
      return;
    }

    final MemcachedClientIF cache = getMemcachedClient();
    final Method methodToCache = getMethodToCache(jp);
    List<UpdateSingleCache> lAnnotations;

    if (methodToCache.getAnnotation(UpdateSingleCache.class) != null) {
      lAnnotations = Arrays.asList(methodToCache.getAnnotation(UpdateSingleCache.class));
    } else {
      lAnnotations = Arrays.asList(methodToCache.getAnnotation(UpdateSingleCaches.class).value());
    }

    for (int i = 0; i < lAnnotations.size(); i++) {
      // This is injected caching.  If anything goes wrong in the caching, LOG the crap outta it,
      // but do not let it surface up past the AOP injection itself.
      try {
        final AnnotationInfo info =
            getAnnotationInfo(lAnnotations.get(i), methodToCache.getName(), getJitterDefault());
        final String baseKey =
            CacheBase.getBaseKey(
                info.getAsString(AType.KEY_TEMPLATE),
                info.getAsInteger(AType.KEY_INDEX, null),
                retVal,
                jp.getArgs(),
                methodToCache.toString(),
                factory,
                methodStore);
        final String cacheKey =
            buildCacheKey(
                baseKey, info.getAsString(AType.NAMESPACE), info.getAsString(AType.KEY_PREFIX));
        Object dataObject =
            getIndexObject(
                info.getAsInteger(AType.DATA_INDEX, null),
                retVal,
                jp.getArgs(),
                methodToCache.toString());
        dataObject =
            UpdateSingleCacheAdvice.getMergedData(
                dataObject,
                info.getAsString(AType.DATA_TEMPLATE, null),
                retVal,
                jp.getArgs(),
                factory);
        final Class dataTemplateType =
            (Class) info.getAsType(AType.DATA_TEMPLATE_TYPE, String.class);
        final Object submission =
            (dataObject == null)
                ? new PertinentNegativeNull()
                : applyDataTemplateType(dataObject, dataTemplateType);

        boolean cacheable = true;
        if (submission instanceof CacheConditionally) {
          cacheable = ((CacheConditionally) submission).isCacheable();
        }

        if (cacheable) {
          cache.set(
              cacheKey,
              calculateJitteredExpiration(
                  info.getAsInteger(AType.EXPIRATION), info.getAsInteger(AType.JITTER)),
              submission);
        }

        // Notify the observers that a cache interaction happened.
        final List<UpdateSingleCacheListener> listeners =
            getPertinentListeners(
                UpdateSingleCacheListener.class, info.getAsString(AType.NAMESPACE));
        if (listeners != null && !listeners.isEmpty()) {
          for (final UpdateSingleCacheListener listener : listeners) {
            try {
              listener.triggeredUpdateSingleCache(
                  info.getAsString(AType.NAMESPACE),
                  info.getAsString(AType.KEY_PREFIX, null),
                  baseKey,
                  dataObject,
                  retVal,
                  jp.getArgs());
            } catch (Exception ex) {
              LOG.warn("Problem when triggering a listener.", ex);
            }
          }
        }
      } catch (Exception ex) {
        if (LOG.isDebugEnabled()) {
          LOG.warn("Caching on " + jp.toShortString() + " aborted due to an error.", ex);
        } else {
          LOG.warn(
              "Caching on " + jp.toShortString() + " aborted due to an error: " + ex.getMessage());
        }
      }
    }
  }