2013-03-13 60 views
2

我想测试是否执行if-else语句, “if”块返回字典/缓存中的项目并返回输出,而“else”块将输入添加到缓存中并返回输出如何在C#中测试if-else语句?

IModifyBehavior的一个方法的接口应用

我有这个类:

namespace Decorator 
{ 
    using System; 

    /// <summary> 
    /// Reverse Behavior 
    /// </summary> 
    public class ReverseBehavior : IModifyBehavior 
    { 
     /// <summary> 
     /// Applies the specified value. 
     /// </summary> 
     /// <param name="value">The value.</param> 
     /// <returns>result</returns> 
     public string Apply(string value) 
     { 
      var result = string.Empty; 
      if (value != null) 
      { 
       char[] letters = value.ToCharArray(); 
       Array.Reverse(letters); 
       result = new string(letters); 
      } 

      return result; 
     } 
    } 
} 




using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Threading.Tasks; 

    /// <summary> 
    /// Caching Decorator 
    /// </summary> 
    public class CachingDecorator : IModifyBehavior 
    { 

     /// <summary> 
     /// The behavior 
     /// </summary> 
     private IModifyBehavior behavior; 


     public CachingDecorator(IModifyBehavior behavior) 
     { 
      if (behavior == null) 
      { 
       throw new ArgumentNullException("behavior"); 
      } 

      this.behavior = behavior; 
     } 



     private static Dictionary<string, string> cache = new Dictionary<string, string>(); 

     /// <summary> 
     /// Applies the specified value. 
     /// </summary> 
     /// <param name="value">The value.</param> 
     /// <returns> 
     /// value 
     /// </returns> 
     public string Apply(string value) 
     { 
      ////Key = original value, Value = Reversed 
      var result = string.Empty; 

      //cache.Add("randel", "lednar"); 
      if(cache.ContainsKey(value)) 
      { 
       result = cache[value]; 
      } 
      else 
      { 
       result = this.behavior.Apply(value);// = "reversed"; 
       ////Note:Add(key,value) 
       cache.Add(value, result); 
      } 
      return result; 
     } 
    } 
} 

这里是我的测试电流的代码,这些代码能够通过测试,但我不知道如果我的实施是正确的:

[TestClass] 
    public class CachingDecoratorTest 
    { 
     private IModifyBehavior behavior; 

     [TestInitialize] 
     public void Setup() 
     { 
      this.behavior = new CachingDecorator(new ReverseBehavior()); 
     } 

     [TestCleanup] 
     public void Teardown() 
     { 
      this.behavior = null; 
     } 

     [TestMethod] 
     public void Apply_Cached_ReturnsReversedCachedValue() 
     { 
      string actual = "randel";   
      ////store it inside the cache 
      string cached = this.behavior.Apply(actual); 

      ////call the function again, to test the else block statement 
      ////Implement DRY principle next time 
      string expected = this.behavior.Apply(actual); 
      Assert.IsTrue(cached.Equals(expected)); 

     } 

     [TestMethod] 
     public void Apply_NotCached_ReturnsReversed() 
     { 
      string actual = "randel"; 
      string expected = "lednar"; 
      Assert.AreEqual(expected, this.behavior.Apply(actual)); 
     } 


    } 

先生/女士您的回答会有很大的帮助。谢谢++

回答

2

首先,我会实际测试两个孤立的clases作为适当的单位。 下面我写了我将如何测试这些。为此,我使用NUnit和Moq(在Nuget中提供)作为嘲讽框架。但是你可以改变测试属性并改用MSTest。

对于我涵盖常规应用和适用于空文的反向行为:

using System; 
using System.Linq; 
using Decorator; 
using NUnit.Framework; 

namespace StackOverflow.Tests.HowToTest 
{ 
    [TestFixture] 
    public class ReverseBehaviorTest 
    { 
     [Test] 
     public void Apply() 
     { 
      const string someText = "someText"; 
      var target = new ReverseBehavior(); 
      var result = target.Apply(someText); 
      Assert.AreEqual(someText.Reverse(), result); 
     } 
     [Test] 
     public void Apply_WhenNull() 
     { 
      var target = new ReverseBehavior(); 
      var result = target.Apply(null); 
      Assert.AreEqual(String.Empty, result); 
     } 
    } 
} 

而对于CachingDecorator,构造函数的异常抛出,与缓存应用和无:

using System; 
using Decorator; 
using Moq; 
using NUnit.Framework; 

namespace StackOverflow.Tests.HowToTest 
{ 
    [TestFixture] 
    public class CachingDecoratorTest 
    { 
     [Test] 
     public void Constructor() 
     { 
      Assert.Throws(typeof(ArgumentNullException),() => new CachingDecorator(null)); 
     } 

     [Test] 
     public void Apply_NotCached() 
     { 
      var internalBehaviorMock = new Mock<IModifyBehavior>(); 
      internalBehaviorMock.Setup(x => x.Apply(It.IsAny<string>())).Returns<string>(y => y); 
      const string someText = "someText"; 
      var target = new CachingDecorator(internalBehaviorMock.Object); 
      target.Apply(someText); 
      internalBehaviorMock.Verify(x => x.Apply(It.IsAny<string>()), Times.Once()); 
     } 

     [Test] 
     public void Apply_Cached() 
     { 
      var internalBehaviorMock = new Mock<IModifyBehavior>(); 
      internalBehaviorMock.Setup(x => x.Apply(It.IsAny<string>())).Returns<string>(y => y); 
      const string someOtherText = "someOtherText"; 
      var target = new CachingDecorator(internalBehaviorMock.Object); 
      target.Apply(someOtherText); 
      target.Apply(someOtherText); 
      internalBehaviorMock.Verify(x => x.Apply(It.IsAny<string>()), Times.Once()); 
     } 
    } 
} 
2

最好的方法是使用一个模拟框架(例如Moq)来创建一个伪造的对象IModifyBehaviour

Apply_NotCached_ReturnsReversed测试然后将验证调用模拟对象的Apply方法以生成结果。 Apply_Cached_ReturnsReversedCachedValue测试将检查返回的结果,而不调用模拟对象的Apply方法。

事实上,您测试缓存的案例实际上并未证明结果来自缓存。

+0

爵士会是确定的,如果只是创建从我试图测试然后修改的if-else返回类似“如果达到”因为如果类继承的stubclass,和“其他人是达到“的其他块? – 2013-03-13 04:42:37

+1

不,因为那样你就没有测试你想要测试的实际方法。 – 2013-03-13 05:00:38

+0

谢谢你的信息先生 – 2013-03-13 06:49:09

0

只是尝试在您的测试用例中设置缓存字典值并在调用Apply(字符串值)方法后检查计数。

​​