C # Comment tester correctement une classe qui suit un modèle de décorateur?

Je suis assez nouveau pour les tests unitaires (je suis en train de l’étudier en ce moment même)

Mon objective est bien sûr de pouvoir tester la méthode dans la classe ci-dessous.

La classe vérifie simplement si l’entrée est déjà dans le cache. Si l’entrée n’est pas dans le cache, elle renverra la forme inversée de l’entrée (bien que l’implémentation ne soit pas ici, mais en supposant qu’elle le soit, car le but est simplement de: tester).

Fondamentalement, l’objective est de s’assurer que le if-else est testé.

Voici ma classe:

namespace YouSource.Decorator { using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; ///  /// Caching Decorator ///  public class CachingDecorator : IModifyBehavior { private IModifyBehavior behavior; private static Dictionary cache = new Dictionary(); public ssortingng Apply(ssortingng value) { ////Key = original value, Value = Reversed var result = ssortingng.Empty; //cache.Add("randel", "lednar"); if(cache.ContainsKey(value)) { result = cache[value]; } else { result = this.behavior.Apply(value);// = "reversed"; cache.Add(value, result); } return result; } } } 

Voici le code actuel de mon test:

 using System; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace YouSource.Decorator.Tests { [TestClass] public class CachingDecoratorTest { private IModifyBehavior behavior; [TestInitialize] public void Setup() { this.behavior = new StubModifyBehavior(new CachingDecorator()); } [TestCleanup] public void Teardown() { this.behavior = null; } [TestMethod] public void Apply_Cached_ReturnsReversedCachedValue() { ssortingng input = "randel"; ssortingng reversed = "lednar"; Assert.AreEqual(reversed, this.behavior.Apply(input)); } [TestMethod] public void Apply_NotCached_ReturnsReversed() { ssortingng input = "not cached"; ssortingng reversed = "reversed"; Assert.AreEqual(reversed, this.behavior.Apply(input)); } public class StubModifyBehavior : IModifyBehavior { private IModifyBehavior behavior; public StubModifyBehavior(IModifyBehavior behavior) { this.behavior = behavior; } public ssortingng Apply(ssortingng value) { //return this.behavior.Apply(value); } } } } 

Le décorateur attache dynamicment un nouveau comportement à l’object décoré. C’est la responsabilité du décorateur. C’est ce que vous devriez tester.

Alors, laisse écrire le décorateur de cache pour le composant suivant:

 public interface IComponent { ssortingng DoSomething(ssortingng value); } 

Création d’un appareil de test (ou TestClass, si vous utilisez MSTest)

 [TestFixture] public class CachingComponentTests { private CachingComponent _cachingComponent; private Mock _componentMock; [SetUp] public void Setup() { _componentMock = new Mock(); // using Moq in this sample _cachingComponent = new CachingComponent(_componentMock.Object); } } 

Pour que ce code soit compilé, vous devez créer la classe CachingComponent, qui accepte le composant décoré. Quelque chose comme ça (peu rapide ici):

 public class CachingComponent : IComponent { private IComponent _component; public CachingComponent(IComponent component) { _component = component; } public ssortingng DoSomething(ssortingng value) { throw new NotImplementedException(); } } 

Définissons maintenant le comportement attendu du décorateur. Il devrait passer un appel à composant, s’il s’agit d’un premier appel avec un paramètre:

 [Test] public void ShouldCallComponentWhenCalledFirstTime() { _componentMock.Setup(c => c.DoSomething("foo")).Returns("bar"); Assert.That(_cachingComponent.DoSomething("foo"), Is.EqualTo("bar")); _componentMock.Verify(); } 

Et cela échoue donc la méthode n’est pas encore implémentée. Première implémentation (enfin, l’implémentation la plus simple retournera null, mais nous avançons un peu plus vite ici):

  public ssortingng DoSomething(ssortingng value) { return _component.DoSomething(value); } 

Agréable. Notre composant de mise en cache fonctionne comme prévu. Mais il ne cache rien. Test écrit pour ça. Il ne devrait appeler le composant qu’une seule fois. Tous les autres appels doivent renvoyer la valeur en cache:

 [Test] public void ShouldReturnCachedValueWhenCalledMoreThanOnce() { _componentMock.Setup(c => c.DoSomething("foo")).Returns("bar"); Assert.That(_cachingComponent.DoSomething("foo"), Is.EqualTo("bar")); Assert.That(_cachingComponent.DoSomething("foo"), Is.EqualTo("bar")); _componentMock.Verify(c => c.DoSomething("foo"), Times.Once()); } 

Et mise en oeuvre:

 public class CachingComponent : IComponent { private Dictionary _cache = new Dictionary(); private IComponent _component; public CachingComponent(IComponent component) { _component = component; } public ssortingng DoSomething(ssortingng value) { if (!_cache.ContainsKey(value)) _cache.Add(value, _component.DoSomething(value)); return _cache[value]; } } 

Vous avez maintenant un décorateur avec un comportement vérifié.