2017-09-27 4 views
1

J'écris des tests unitaires pour mon application API Web asp.net et l'un d'entre eux essaie de vérifier que AddOrGetExisting fonctionne correctement. Selon la documentation MSDN, AddOrGetExisting renvoie un élément s'il est déjà enregistré et, dans le cas contraire, il doit l'écrire dans le cache. Le problème que j'ai est que si j'ajoute la clé à l'objet MemoryCache d'un test unitaire, alors appelez AddOrGetExisting, il renverra toujours null et remplacera la valeur au lieu de retourner la valeur qui est déjà sauvée. Je vérifie que la valeur est dans le cache juste avant que j'appelle AddOrGetExisting (bool isIn évalue à vrai).MemoryCache.Default.AddOrGetExisiting renvoie null bien que la clé soit dans le cache

Voici le code pour ma mémoire cache et la méthode de test. Toute aide serait appréciée:

public static class RequestCache 
{ 
    public static TEntity GetFromCache<TEntity>(string key, Func<TEntity> valueFactory) where TEntity : class 
    { 
     ObjectCache cache = MemoryCache.Default; 
     var newValue = new Lazy<TEntity>(valueFactory); 
     CacheItemPolicy policy = new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(60) }; 
     bool isIn = cache.Contains(key); 
     // Returns existing item or adds the new value if it doesn't exist 
     var value = cache.AddOrGetExisting(key, newValue, policy) as Lazy<TEntity>; 
     return (value ?? newValue).Value; 
    } 

}

public string TestGetFromCache_Helper() 
    { 
     return "Test3and4Values"; 
    } 

    [TestMethod] 
    public void TestGetFromCache_ShouldGetItem() 
    { 
     ObjectCache cache = MemoryCache.Default; 
     CacheItemPolicy policy = new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(60) }; 
     var cacheKey = "Test3"; 
     var expectedValue = "Test3Value"; 
     cache.AddOrGetExisting(cacheKey, expectedValue, policy); 

     var result = Models.RequestCache.GetFromCache(cacheKey, 
      () => 
       { 
        return TestGetFromCache_Helper(); 
       }); 

     Assert.AreEqual(expectedValue, result); 
    } 

Répondre

1

Le problème peut être que vous passez un Lazy<TEntity> comme newValue au sein RequestCache.GetFromCache, mais le passage d'un string comme expectedValue dans la méthode d'essai.

Lors de l'exécution du test, le cache.Contains(key) confirme l'existence d'une valeur stockée pour cette clé, ce qui est vrai. Cependant, il s'agit d'un string au lieu d'un Lazy<TEntity>. Apparemment, AddOrGetExisting décide d'écraser la valeur dans ce cas.

Le correctif pour ce scénario particulier peut être d'ajuster l'affectation expectedValue dans votre test à quelque chose comme ceci:

var expectedValue = new Lazy<string>(TestGetFromCache_Helper); 

Vous aurait également besoin de tirer la valeur de la Lazy par rapport à l'égalité finale de l'épreuve , par exemple:

Assert.AreEqual(expectedValue.Value, result); 
+1

Merci! C'est exactement ce qui n'allait pas. Juste une édition au cas où quelqu'un aurait le même problème dans le futur: Au lieu d'appeler le nouveau Lazy (TestGetFromCache_Helper), puisque cela retournerait la même valeur et passerait le test indépendamment du fait qu'il était écrasé ou non, j'ai créé une seconde fonction auxiliaire cela renvoie "Test3Value", puis appelez nouveau Lazy (TestGetFromCache_Helper2) – sgonzalez