Ran*_*rez 5 .net c# unit-testing design-patterns
我对单元测试比较陌生(我实际上正在研究它)
我的目标当然是能够在下面的课程中测试方法.
该类只是检查输入是否已经在缓存中,如果输入不在缓存中,它将返回输入的反转形式(虽然实现不在这里,但假设确实如此,因为目的只是为了测试).
基本上,目标是确保测试if-else.
这是我的班级:
namespace YouSource.Decorator
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/// <summary>
/// Caching Decorator
/// </summary>
public class CachingDecorator : IModifyBehavior
{
private IModifyBehavior behavior;
private static Dictionary<string, string> cache =
new Dictionary<string, string>();
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";
cache.Add(value, result);
}
return result;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我测试的当前代码:
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()
{
string input = "randel";
string reversed = "lednar";
Assert.AreEqual(reversed, this.behavior.Apply(input));
}
[TestMethod]
public void Apply_NotCached_ReturnsReversed()
{
string input = "not cached";
string reversed = "reversed";
Assert.AreEqual(reversed, this.behavior.Apply(input));
}
public class StubModifyBehavior : IModifyBehavior
{
private IModifyBehavior behavior;
public StubModifyBehavior(IModifyBehavior behavior)
{
this.behavior = behavior;
}
public string Apply(string value)
{
//return this.behavior.Apply(value);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
装饰器动态地将新行为附加到装饰的对象.这是装饰者的责任.那是你应该测试的.
所以,让我们为以下组件编写缓存装饰器:
public interface IComponent
{
string DoSomething(string value);
}
Run Code Online (Sandbox Code Playgroud)
创建测试夹具(或TestClass,如果您使用的是MSTest)
[TestFixture]
public class CachingComponentTests
{
private CachingComponent _cachingComponent;
private Mock<IComponent> _componentMock;
[SetUp]
public void Setup()
{
_componentMock = new Mock<IComponent>(); // using Moq in this sample
_cachingComponent = new CachingComponent(_componentMock.Object);
}
}
Run Code Online (Sandbox Code Playgroud)
要编译此代码,您需要创建CachingComponent类,该类接受修饰组件.像这样的东西(这里加速度很小):
public class CachingComponent : IComponent
{
private IComponent _component;
public CachingComponent(IComponent component)
{
_component = component;
}
public string DoSomething(string value)
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
现在让我们定义装饰器的预期行为.它应该将调用传递给组件,如果是第一次使用某个参数调用:
[Test]
public void ShouldCallComponentWhenCalledFirstTime()
{
_componentMock.Setup(c => c.DoSomething("foo")).Returns("bar");
Assert.That(_cachingComponent.DoSomething("foo"), Is.EqualTo("bar"));
_componentMock.Verify();
}
Run Code Online (Sandbox Code Playgroud)
它失败了因此方法尚未实现.第一个实现(好吧,最简单的实现将返回null,但我们在这里移动得更快):
public string DoSomething(string value)
{
return _component.DoSomething(value);
}
Run Code Online (Sandbox Code Playgroud)
尼斯.我们的缓存组件按预期工作.但它并没有缓存任何东西.为此编写测试.它应该只调用一次组件.所有进一步的调用应该返回缓存的值:
[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());
}
Run Code Online (Sandbox Code Playgroud)
并实施:
public class CachingComponent : IComponent
{
private Dictionary<string, string> _cache = new Dictionary<string, string>();
private IComponent _component;
public CachingComponent(IComponent component)
{
_component = component;
}
public string DoSomething(string value)
{
if (!_cache.ContainsKey(value))
_cache.Add(value, _component.DoSomething(value));
return _cache[value];
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您已经使用经过验证的行为缓存装饰器.