2

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

3 に答える 3

2

まず、適切な単位として、実際に2つのクラスを分離してテストします。以下に、これらをテストする方法を書き留めました。このために、モックフレームワークとしてNUnitとMoq(Nugetで利用可能)を使用しています。ただし、テスト属性を変更して、代わりにMSTestを使用することができます。

逆の動作については、通常の適用とnullテキストへの適用の両方をカバーしています。

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());
        }
    }
}
于 2013-03-13T04:55:25.060 に答える
2

最善の方法は、モック フレームワーク (たとえば Moq など) を使用して偽のIModifyBehaviourオブジェクトを作成することです。

Apply_NotCached_ReturnsReversedテストApplyでは、モック オブジェクトのメソッドが呼び出されて結果が生成されたことを確認します。このテストでは、モック オブジェクトApply_Cached_ReturnsReversedCachedValueのメソッドを呼び出さずに結果が返されたことを確認します。Apply

そのままでは、キャッシュされたケースをテストしても、結果がキャッシュからのものであることを実際に証明することはできません。

于 2013-03-13T04:29:54.960 に答える
0

テストケースでキャッシュ ディクショナリの値を設定し、Apply(string value) メソッドを呼び出した後にカウントを確認してみてください。

` 
       public void Apply_Cached_ReturnsReversedCachedValue()
        {
            Dictionary<string, string> cacheDict = new Dictionary<string, string>() { { "sometext", "txetemos" } };

            string str = "sometext";

            int dictionaryCountBeforeApply = cacheDict.Count();

            //set value to static cache field using reflection, here dictionary count is 1
            Type type = typeof(CachingDecorator);
            FieldInfo cacheFieldInfo = type.GetField("cache", BindingFlags.NonPublic | BindingFlags.Static);
            cacheFieldInfo.SetValue(decorator, cacheDict);

            string result = decorator.Apply(str);

            int dictionaryCountAfterApply = cacheDict.Count();

            Assert.AreEqual(dictionaryCountAfterApply, dictionaryCountBeforeApply);
        }


        public void Apply_NotCached_ReturnsReversed()
        {
            Dictionary<string, string> cacheDict = new Dictionary<string, string>() { };
            string str = "sometext";

            int dictionaryCountBeforeApply = cacheDict.Count();

            //set value to static cache field using reflection, here dictionary count is 0
            Type type = typeof(CachingDecorator);
            FieldInfo cacheFieldInfo = type.GetField("cache", BindingFlags.NonPublic | BindingFlags.Static);
            cacheFieldInfo.SetValue(decorator, cacheDict);

            string result = decorator.Apply(str);

            int dictionaryCountAfterApply = cacheDict.Count();

            Assert.AreNotEqual(dictionaryCountAfterApply, dictionaryCountBeforeApply);
        }`
于 2013-03-13T06:11:01.893 に答える