2013-03-12 25 views
5

Tôi khá mới để thử nghiệm đơn vị (tôi thực sự đang nghiên cứu nó khi chúng tôi nói)C# Làm thế nào để đơn vị đúng kiểm tra một lớp học mà theo một mẫu trang trí?

Mục tiêu của tôi tất nhiên là có thể kiểm tra phương thức bên trong lớp bên dưới. Lớp học chỉ đơn giản là kiểm tra nếu đầu vào đã có trong bộ nhớ cache, nếu đầu vào không có trong bộ đệm, nó sẽ trả về dạng đảo ngược của đầu vào (mặc dù việc thực hiện không có ở đây, nhưng giả sử nó có, vì mục đích chỉ là để kiểm tra).

Về cơ bản, mục tiêu là đảm bảo nếu người khác được kiểm tra.

Đây là lớp học của tôi:

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; 
     } 
    } 
} 

Đây là mã hiện tại của thử nghiệm của tôi:

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); 
      } 
     } 
    } 
} 

Trả lời

7

Decorator động gắn hành vi mới cho đối tượng được trang trí. Đó là trách nhiệm của người trang trí. Đó là những gì bạn nên kiểm tra.

Vì vậy, cho phép ghi bộ nhớ đệm trang trí cho thành phần sau đây:

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

Tạo bộ ghép đo (hoặc TestClass, nếu bạn đang sử dụng 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); 
    } 
} 

Đối với mã này để biên dịch bạn cần phải tạo Lớp CachingComponent, chấp nhận thành phần trang trí. Một cái gì đó như thế (ít tốc độ lên đây):

public class CachingComponent : IComponent 
{ 
    private IComponent _component; 

    public CachingComponent(IComponent component) 
    {    
     _component = component; 
    } 

    public string DoSomething(string value) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Bây giờ, hãy xác định hành vi mong đợi của trang trí. Nó sẽ chuyển cuộc gọi đến thành phần, nếu đó là lần đầu tiên gọi với một số tham số:

[Test] 
public void ShouldCallComponentWhenCalledFirstTime() 
{ 
    _componentMock.Setup(c => c.DoSomething("foo")).Returns("bar"); 

    Assert.That(_cachingComponent.DoSomething("foo"), Is.EqualTo("bar")); 
    _componentMock.Verify(); 
} 

Và do đó phương pháp này không được thực hiện. Triển khai đầu tiên (tốt, triển khai đơn giản nhất sẽ trả về null, nhưng chúng tôi đang di chuyển nhanh hơn ở đây):

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

Rất tốt. Thành phần bộ nhớ đệm của chúng tôi hoạt động như mong đợi. Nhưng nó không phải là bộ nhớ đệm bất cứ điều gì. Viết bài kiểm tra cho điều đó. Nó chỉ nên gọi thành phần một lần. Tất cả các cuộc gọi tiếp tục phải trả lại giá trị được lưu trữ:

[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()); 
} 

Và thực hiện:

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]; 
    } 
} 

Bây giờ bạn có bộ nhớ đệm trang trí với hành vi đã xác minh.

Các vấn đề liên quan