Thursday, February 12, 2009

Unit testing CAB applications

Creating unit tests is a quite challenging thing to do when creating a CAB application. Especially with the dependencies built during runtime by dependency injection that the CAB depends on. The main requirement for creating a unit test project for CAB is a Testable workitem. The TestableWorkItem class holds all the items required by the Dependency Injection framework while running the tests.
public class TestableRootWorkItem : WorkItem
{
public TestableRootWorkItem()
{
InitializeRootWorkItem(CreateBuilder());
Services.AddNew();
Services.AddNew();
Services.AddNew();
}
public Builder Builder
{
get { return InnerBuilder; }
}
public IReadWriteLocator Locator
{
get { return InnerLocator; }
}
private Builder CreateBuilder()
{
Builder builder = new Builder(); builder.Strategies.AddNew(BuilderStage.Initialization); builder.Strategies.AddNew(BuilderStage.Initialization); builder.Strategies.AddNew(BuilderStage.PostInitialization);
builder.Policies.SetDefault(new ObjectBuiltNotificationPolicy());
return builder;
}
}

Mocks can be created using any Mocking Framework. In this example I have used Rhino Mocks. The dependencies can be added to the TesttableWorkItem class during the TestInitialize stage and then get it resolved in the TestMethods
[TestInitialize()]
public void MyTestInitialize()
{
IEmployeeService _employeeService = mocks.StrictMock();
IListEmployeesView view = mocks.StrictMock();

using (mocks.Record())
{
Expect.Call(_employeeService.GetCount()).Return(4);
}
workItem = new TestableRootWorkItem();
workItem.Services.Add(_employeeService);
eventPublisher = workItem.Items.AddNew();
eventSubscriber = workItem.Items.AddNew();
presenter = workItem.Items.AddNew();
presenter.View = view;
}
[TestMethod()]
public void GetCountTest()
{
int expected = 4;
int actual;
actual = presenter.GetCount();
Assert.AreEqual(expected, actual, "Count returned did not match the expected value");
}
[TestMethod]
public void EventPublicationSubscriptionTest()
{
eventPublisher.OnInsertEmployee(new EventArgs("Prajeesh"));
Assert.AreEqual(true, eventPublisher.NewEmployeeEventRaised, "Failed to raise event publication");
Assert.AreEqual(true, eventSubscriber.NewEmployeeEventHandled, "Failed to handle event publication");
}

No comments: