• Windows Azure Storage: TDD and mocks

    Published by fboerr on July 23rd, 2010 6:27 pm under Emerging Technology, azure

    1 Comment

    During the last months, we have been working on a sample application for the Windows Azure Architecture Guide.

    One of the challenges we want to face in the development side is to develop the majority of the sample application following TDD practices.

    This post shows how we mocked-up Azure Storage Tables by using a IAzureTable interface. Similar interfaces have been develop for queues (IAzureQueue) and blobs (IAzureBlobContainer).

    Thanks Johnny Halife (@johnnyhalife), Juan Pablo Garcia (@jpgd) and Scott Densmore (@scottdensmore). These classes have been designed after long discussions with you guys so you also hold credit for them.

    Directly using WindowsAzure.StorageClient (from Windows Azure SDK)

    When developing applications for Windows Azure, the most used  library for accessing the Azure Storage is the Storage Client (Microsoft.WindowsAzure.StorageClient) that comes as part of the Windows Azure SDK.

    As an example, let’s imagine we are developing the SurveyStore (this class is part of the Storage component in the diagram above). This class that is called from the controllers and interacts with the persistence stores.

    spacer

    SurveyStore using WindowsAzure.StorageClient

    public class SurveyStore : ISurveyStore
    {
    private readonly CloudStorageAccount account;

    public SurveyStore(CloudStorageAccount account)
    {
    this.account = account;
    }

    public IEnumerable<Survey> GetSurveysByTenant(string tenant)
    {

    var cloudTableClient = new CloudTableClient(this.account.TableEndpoint.ToString(), this.account.Credentials);
    cloudTableClient.CreateTableIfNotExist(“SurveysTable”);

    TableServiceContext context = this.CreateContext();

    var query = (from s in context.CreateQuery<SurveyRow>(“SurveysTable”)
    where s.PartitionKey == tenant
    select s).AsTableServiceQuery();

    return query.Execute().Select(surveyRow => new Survey(surveyRow.SlugName)
    {
    Tenant = surveyRow.PartitionKey,
    Title = surveyRow.Title,
    CreatedOn = surveyRow.CreatedOn
    }).ToList();
    }
    }

    Testing this implementation

    If we want to write a test for this method, this would be a functional test because there is no way to mockup the calls to CloudTableClient and to TableServiceContext.

    Every time we run the test, we have to:

    1. Ensure the data we will query is exactly what we are expecting to get (2 calls to the real Surveys Table in the Azure storage)

    2. Call GetSurveysByTenant (1 call to the real Surveys Table in the Azure storage)

    3. Assert that we got what we were expecting from the store

    [TestMethod]
    public void GetSurveysByTenant()
    {
    var expenseContext = AzureStorageHelper.GetContext();

    var expected = new Expense { Tenant = “Tenant”,  (… initialize other properties …) };
    expected.Details.Add(new ExpenseItem { (… initialize all properties …) });
    AzureStorageHelper.DeleteExpenseAndItemsById(expenseContext, expected.Id);
    AzureStorageHelper.SaveExpense(expenseContext, expected);

    var store = new ExpenseStore();
    var expenses = store.GetSurveysByTenant(“Tenant”);

    Assert.AreEqual(1, expenses.Count());
    var actual = expenses.Single(e => e.Id == expected.Id);
    Assert.AreEqual(“Tenant”, actual.Tenant);

    (Assert other properties …)
    }

    Wrapping WindowsAzure.StorageClient with an IAzureTable

    In the case our development is driven by TDD or we just want to write unit tests on any class that has to interact with Windows Azure Storage, we find a problem with the implementation shown above.

    Working with CloudTableClient or TableServiceContext will not allow us to write *unit* tests. Testing the previous implementation, implied not only testing the SurveyStore class code, but also the code to access the Windows Azure Table itself. The ONLY way to test the SurveyStore code, is writing stubs and mocks for the code that access the Windows Azure Table.

    This implementation also follows a good object-oriented design: “Program to an ‘interface’, not an ‘implementation’” and provides all its advantages.

    SurveyStore using IAzureTable

    public class SurveyStore : ISurveyStore
    {
    private readonly IAzureTable<SurveyRow> surveyTable;

    public SurveyStore(IAzureTable<SurveyRow> surveyTable)
    {
    this.surveyTable = surveyTable;
    }

    public IEnumerable<Survey> GetSurveysByTenant(string tenant)
    {
    var query = from s in this.surveyTable.Query
    where s.PartitionKey == tenant
    select s;

    return query.ToList().Select(surveyRow => new Survey(surveyRow.SlugName)
    {
    Tenant = surveyRow.PartitionKey,
    Title = surveyRow.Title,
    CreatedOn = surveyRow.CreatedOn
    });
    }
    }

    Testing this implementation

    Testing this implementation is easier and let us focus ONLY in 1 part at a time.

    In this example, we are only testing that the method GetSurveysByTenant correctly copies the title from the row read from the IAzureTable (SurveysTable) to the returned survey.

    By mocking the IAzureTable, we can setup what the Query property is going to return, so there is no need to interact with the Windows Azure Storage itself. Remember that in the previous implementation we had to make 3 calls to the Windows Azure Table. Here, we are making no calls to the Windows Azure Table.

    [TestMethod]
    public void GetSurveysByTenantReturnsTitle()
    {
    var surveyRow = new SurveyRow { PartitionKey = “tenant”, Title = “title” };
    var surveyRowsToReturn = new[] { surveyRow };
    var mock = new Mock<IAzureTable<SurveyRow>>();
    mock.SetupGet(t => t.Query).Returns(surveyRowsToReturn.AsQueryable());
    var store = new SurveyStore(mock.Object, default(IAzureTable<QuestionRow>));

    var actualSurveys = store.GetSurveysByTenant(“tenant”);

    Assert.AreEqual(“title”, actualSurveys.First().Title);
    }

  • 1 Comment:

    1. Twitter Trackbacks for Federico Boerr’s Blog » Blog Archive » Windows Azure Storage: TDD and mocks [southworks.net] on Topsy.com said on July 23, 2010:

      [...] Federico Boerr’s Blog » Blog Archive » Windows Azure Storage: TDD and mocks blogs.southworks.net/fboerr/2010/07/23/windows-azure-storage-tdd-and-mocks/ – view page – cached During the last months, we have been working on a sample application for the Windows Azure Architecture Guide. Tweets about this link [...]

    Leave a comment

    Your email address will not be published.

Recent Posts

  • Sliding sessions in SharePoint 2010
  • Create a WCF Data Service (OData) to share an Azure Table
  • Windows Azure Storage: TDD and mocks
  • Escaping illegal characters for Azure row key and partition key
  • Compsition in Windows Azure Table Storage: choosing the row key and simulating StartsWith

Map

spacer

Categories

  • AddIn (2)
  • agile (1)
  • azure (2)
  • CardSpace (6)
  • Emerging Technology (4)
  • identity (1)
  • Memory Leaks (1)
  • Uncategorized (1)
  • WPF (1)

Archives

  • April 2011 (1)
  • July 2010 (2)
  • April 2010 (2)
  • March 2009 (2)
  • June 2008 (3)
  • December 2007 (5)
  • September 2007 (1)
gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.