Programmers who have incorporated unit testing into their development process already know its advantages: cleaner code, courage to refactor, and higher speed. Writing tests is easy; it is writing good tests that makes automated unit testing a powerful tool. This article provides some basic information on using Rhino Mocks 3.5 to write unit test cases in the Arrange Act Assert pattern.
· Arrange - set up the unit under test
· Act - exercise the unit under test, capturing any resulting state
- Assert - verify the behavior through assertions
I have two main base classes in this sample that handles the functionality of Mocking and AAA.
The base repository class contains the mock creating methods
public class BaseRepository
{
public MockRepository MockRepository = new MockRepository();
public TMock Mock
{
return MockRepository.StrictMock
}
public TStub Stub
{
return MockRepository.Stub
}
protected IDisposable PlayBack
{
get { return MockRepository.Playback(); }
}
protected IDisposable Record
{
get { return MockRepository.Record(); }
}
protected IDisposable PlayBackOnly
{
get
{
using (Record) { }
return PlayBack;
}
}
}
The ArrangeActAssertTearDown class contains methods that implement the AAA pattern.
public abstract class ArrangeAssertActTearDown
{
public T SystemUnderTest { get; private set; }
[TestInitialize]
public void Initialize()
{
Arrange();
SystemUnderTest = CreateSUT();
Act();
}
[TestCleanup]
public virtual void BasicTearDown()
{
TearDown();
}
public abstract void Arrange();
public virtual T CreateSUT()
{
return new T();
}
public abstract void Act();
public abstract void TearDown();
}
Implementing the pattern and writing test cases is as simple as
[TestClass()]
public class When_Getting_All_Products_From_Store : ArrangeAssertActTearDown<ProductService>
{
private IProductRepository ___ProductRepository;
private IStoreRepository ___StoreRepository;
private Store ___Store;
private IEnumerable<Product> ___Products;
private long __StoreIntId = 3;
public override void Arrange()
{
___ProductRepository = Mock<IProductRepository>();
___StoreRepository = Mock<IStoreRepository>();
}
public override ProductService CreateSUT()
{
return new ProductService(___ProductRepository, ___StoreRepository);
}
public override void Act()
{
___Store = new Store();
___Products = new List<Product>();
using (Record)
{
SetupResult.For<Store>(___StoreRepository.FindBy(0))
.IgnoreArguments()
.Return(___Store);
SetupResult.For<IEnumerable<Product>>(___ProductRepository.GetAllProductsFor(null))
.IgnoreArguments()
.Return(___Products);
}
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void Should_Throw_Argument_Exception_If_StoreId_Is_Greater_Than_100()
{
___StoreRepository.BackToRecord(BackToRecordOptions.All);
___ProductRepository.BackToRecord(BackToRecordOptions.All);
var __Target = new ProductService();
var __Result = __Target.GetAllProductsForStore(110);
}
[TestMethod]
public void Should_Return_A_List_Of_Records()
{
using (PlayBack)
{
var __Result = SystemUnderTest.GetAllProductsForStore(__StoreIntId);
Assert.AreEqual<IEnumerable<Product>>(__Result, ___Products);
}
}
public override void TearDown()
{
___ProductRepository = null;
___StoreRepository = null;
}
}
No comments:
Post a Comment