1

我想测试 if-else 语句是否被执行,“if”块从字典/缓存中返回项目并返回输出,而“else”块在缓存中添加输入并返回输出

带有方法 Apply 的 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));
        }


    }

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

4

2 回答 2

2

我认为您会想要一个真正执行类合同的单元测试,而不必过多担心内部结构。例如,您可以通过反射做某事,或者公开一些新方法,让您的测试询问缓存它在做什么,但您的测试无论如何都不应该关心这些。如果我查看缓存装饰器,您所暗示的合同类似于:

一旦apply使用参数x和返回值v调用,任何随后对apply参数的调用x也将返回v

因此,正如您已经拥有的那样,调用该方法两次的测试x可以表明我们两次都v返回。但是我们不能说这是因为缓存装饰器正在做我们想要的,或者是因为底层的反转修饰符只是遵循合同。

那么,如果我们有一个不符合这些规则的潜在修饰符呢?

假设,使用一个模拟,你设置了一个IModifyBehavior返回它被调用次数的实现?现在我们有了不同的行为——如果我用相同的参数在这个实现上调用 apply 3 次x,我会得到 3 个不同的答案(可以通过单元测试来验证)。如果我随后将该模拟包装在您的 CachingDecorator 中,我可以看到 CachingDecorator 挂在它看到的第一个调用上,并遵守原始合同。这向我“证明”了 CachingDecorator 的内部结构遵循合同,而不是仅仅将调用传递给恰好也遵循合同的其他对象。

于 2013-03-13T17:26:42.457 回答
0

我的第一个问题是你为什么反对使用模拟框架?

但是在这种情况下,为什么不直接滚动你自己的模拟,请参阅滚动你自己的模拟对象,这可以在不使用外部库的情况下解决你的问题。

于 2013-03-13T17:43:41.980 回答