2010-08-16 21 views
6

J'écris des tests sur notre mécanisme Caching et je veux être sûr que ce qui entre dans le cache est le même que ce qui sort, c'est-à-dire que toutes les propriétés correspondent. Voici un exemple fictif de la façon dont je voudrais que cela fonctionneEffectuez Assert.AreMatch() pour comparer les propriétés dans deux objets

[Test] 
    public void add_client_model_member_to_cache_then_retreve() 
    { 
     //arrange 
     MemcachedClient client = new MemcachedClient(); 
     Member member = GetMember(); 
     client.Store(StoreMode.Set, "membertest", member); 

     // act 
     var result = client.Get<Member>("membertest"); 

     // assert 
     Assert.AreMatch(result, member); 
    } 

Il est impossible d'effectuer Assert.AreEqual sur chaque propriété car il y aura beaucoup de ces tests avec de nombreuses propriétés dans chacune.

Wow, merci Jon. Je pense que vous avez répondu en moins d'une minute. Voici ma solution résultante pour toutes les parties intéressées. J'ai implémenté comme Jon l'a suggéré (je pense) mais j'ai eu un petit problème avec les propriétés du tableau et en tant que tel ma solution ne gère que les tableaux d'ints (tout ce dont j'ai besoin actuellement).

Il est également devenu une pente assez glissante si j'essaie de vérifier plus d'un niveau. Je suis sûr que cela peut être atteint mais pour mes fins, il n'est pas nécessaire.

private bool AreMatch(object initial, object result) 
    { 
     if (initial.Equals(result)) 
      return true; 

     foreach (var property in initial.GetType().GetProperties()) 
     { 
      var initialPropValue = property.GetValue(initial,null); 
      var resultPropValue = result.GetType().GetProperty(property.Name).GetValue(result,null); 

      if (property.PropertyType.IsArray) 
      { 
       if ((initialPropValue != null && resultPropValue != null) && !Enumerable.SequenceEqual((int[])initialPropValue, (int[])resultPropValue)) 
         return false;     
      } 
      else if (!object.Equals(initialPropValue, resultPropValue)) 
      { 
       return false; 
      } 
      else if (initialPropValue != null && property.PropertyType.IsClass) 
      { 
       // Don't go deeper than one level, this got me into trouble 
       //if (!AreMatch(initialPropValue, resultPropValue)) 
       // return false; 
      } 
     } 
     return true; 
    } 

La méthode ci-dessus peut être utilisé dans les situations suivantes

[Test] 
    public void cached_result_is_same_as_original() 
    { 
     //arrange 
     Member member = GetMember(); 
     client.Store(StoreMode.Set, "membertest", member); 

     // act 
     var result = client.Get<Member>("membertest"); 

     // assert 
     Assert.IsTrue(AreMatch(member, result)); 
    } 

    [Test] 
    public void cached_result_is_same_as_original() 
    { 
     //arrange 
     Member member = GetMember(); 
     client.Store(StoreMode.Set, "membertest", member); 

     // act 
     var result = client.Get<Member>("membertest"); 
     result.FirstName = "Result is different"; 

     // assert 
     Assert.IsFalse(AreMatch(member, result)); 
    } 
+0

une solution? – Kiquenet

+0

J'ai ajouté la solution que j'ai utilisée à la question (voir ci-dessus) .. il pourrait être ajouté à la prise en charge de la traversée de propriétés à plusieurs niveaux, mais cela n'était pas nécessaire et peut devenir assez désordonné assez rapidement. – CodeKiwi

Répondre

3

Eh bien, vous pouvez certainement écrire quelque chose à récursif à travers toutes les propriétés et appeler object.Equals sur le résultat de la récupération de la valeur de la propriété de les attendus et les réels. Utilisez Type.GetProperties() pour obtenir les propriétés elles-mêmes, et PropertyInfo.GetValue pour obtenir la valeur.

Ce sera un peu brut, mais vous pouvez toujours le modifier si nécessaire.