Writing Tests for HealthVault Applications

Posted by: Eric Gunnersons C# Compendium, on 18 Jan 2011 | View original | Bookmarked: 0 time(s)

We have added some useful new functionality designed to make it easier to test a HealthVault application.

The existing HealthVault SDKs didn’t make it easy if you wanted to write isolated (or method-level) unit tests for features that talked to the HealthVault Platform. You could usually do it by designing your own layer that could return simulated results (sometimes called “mocking” in agile methodologies), but that was sometimes difficult because of the way the SDK worked.

In this release, we’ve made some changes that should make this a whole lot easier.

For the sake of discussion, consider a bit of application code that fetches medications from HealthVault and filters them:

         HealthRecordItemCollection GetNewMedications(HealthRecordAccessor record)
         {
             HealthRecordSearcher searcher = record.CreateSearcher(Medication.TypeId);
             HealthRecordItemCollection items = searcher.GetMatchingItems()[0];
             // filter items here... 

We want to write a test that verifies that the “filter items here” part of the method works correctly, and we’d like the test to run without talking to the HealthVault platform. That’s not easy to do in the current SDK, because there’s no way to control what comes back from GetMatchingItems().

In the new SDK, there is a way to do that. If we debug down we will find that the call to GetMatchingItems ends up in the following method in a new class named HealthVaultPlatform.

 

         public  static  ReadOnlyCollection <HealthRecordItemCollection > GetMatchingItems(
             ApplicationConnection  connection,
             HealthRecordAccessor  accessor,
             HealthRecordSearcher  searcher)
         {
             return  HealthVaultPlatformItem .Current.GetMatchingItems(connection, accessor, searcher);
         }
 

The HealthVaultPlatform class centralizes all operations (except for one exception I’ll cover later) in a single class – if the SDK needs to talk to HealthVault it goes through that class. You can call into that class directly if you wish, or just troll through to see what operations can be performed.

To create our test, we are going to be hooking in underneath that level. The method above just forwards into a method in the HealthVaultPlatformItem class, and that class provides a way for us to override the behavior.

To get started, we need to create a class that derives from HealthVaultPlatformItem and overrides the GetMatchingItems() method. The first version looks like this:

     public  class  HealthVaultPlatformItemMock  : HealthVaultPlatformItem

We can use it like this (this is an NUnit test):

         [Test]
         public  void  GetMatchingItems()

When the call to GetMatchingItems() gets down to HealthVaultPlatformItems, it will end up calling our mocked method rather than the built-in one.

The code requires us to do a few things:

  1. Create an instance of the mock class.
  2. Enable the mock.
  3. Disable the mock.

We can make it nicer by having the mock class handle enabling and disabling the mock, using the following:

     public  class  HealthVaultPlatformItemMock  : HealthVaultPlatformItem, IDisposable 

Special Classes

There are a few classes where it’s not straightforward to create the class. For classes such as ServiceInfo, we don’t provide a way to create and modify them directly. To create an instance of those classes, you need to derive a new class and use that:

     public  class  ServiceInfoTest  : ServiceInfo

and the associated test uses this class instead of ServiceInfo:

         [Test]
         public  void  GetServiceInfoTest()

 

Limitations

We currently don’t have mockable interfaces for blob operations. We hope to do that in a future release.

         {
             ApplicationConnection connection = new  ApplicationConnection(Guid .NewGuid());
 
             ServiceInfoTest serviceInfo = new  ServiceInfoTest("V2.x" );
 
             ServiceInfo serviceInfoBack = null ;
             using  (HealthVaultPlatformInformationMock mock = new  HealthVaultPlatformInformationMock(serviceInfo))
             {
                 serviceInfoBack = connection.GetServiceDefinition();
             }
 
             Assert.AreEqual("V2.x" , serviceInfoBack.Version);
         }
 
     {
         public  ServiceInfoTest(string  version)
         {
             Version  = version;
         }
     }
 
     {
         HealthRecordItemCollection _itemsToReturn;
 
         public  HealthVaultPlatformItemMock(params  HealthRecordItem[] items)
         {
             _itemsToReturn = new  HealthRecordItemCollection(items);
             HealthVaultPlatformItem.EnableMock(this );
         }
 
         public  override  ReadOnlyCollection <HealthRecordItemCollection> GetMatchingItems(
             ApplicationConnection connection, 
             HealthRecordAccessor accessor, 
             HealthRecordSearcher searcher)
         {
             List <HealthRecordItemCollection> collections = new  List <HealthRecordItemCollection>();
             collections.Add(_itemsToReturn);
 
             return  new  ReadOnlyCollection <HealthRecordItemCollection>(collections);
         }
 
         #region  IDisposable
         ~HealthVaultPlatformItemMock()
         {
             Dispose(false );
         }
 
         /// <summary> 
         /// Disposes the request. 
         /// </summary> 
         ///  
         public  void  Dispose()
         {
             Dispose(true );
             GC.SuppressFinalize(this );
         }
 
         /// <summary> 
         /// Disables the mocking. 
         /// </summary> 
         ///  
         /// <param name="disposing"></param> 
         ///  
         protected  void  Dispose(bool  disposing)
         {
             HealthVaultPlatformItem.DisableMock();
         }
 
         #endregion  IDisposable
  
     }
 
That allows us to simplify our test code to this:
 
         [Test]
         public  void  GetMatchingItems()
 
         {
             Medication medication = new  Medication(new  CodableValue("Ibuprofen" ));
             Medication medication2 = new  Medication(new  CodableValue("Vitamin C" ));
 
             HealthRecordItemCollection newItems = null ;
             using  (HealthVaultPlatformItemMock mock = new HealthVaultPlatformItemMock(medication, medication2))
             {
                 ApplicationConnection connection = new  ApplicationConnection(Guid .NewGuid());
                 HealthRecordAccessor accessor = new  HealthRecordAccessor(connection, Guid .NewGuid());
                 newItems = GetNewMedications(accessor);
             }
 
             Assert.AreEqual(2, newItems.Count);
             Assert.AreEqual("Ibuprofen" , ((Medication) newItems[0]).Name.Text);
             Assert.AreEqual("Vitamin C" , ((Medication) newItems[1]).Name.Text);
         }
     
     
         {
             Medication medication = new  Medication(new  CodableValue("Ibuprofen" ));
             Medication medication2 = new  Medication(new  CodableValue("Vitamin C" ));
 
             HealthRecordItemCollection newItems = null ;
             HealthVaultPlatformItemMock mock = new  HealthVaultPlatformItemMock(medication, medication2);
             HealthVaultPlatformItem.EnableMock(mock);
             ApplicationConnection connection = new  ApplicationConnection(Guid .NewGuid());
             HealthRecordAccessor accessor = new  HealthRecordAccessor(connection, Guid .NewGuid());
             newItems = GetNewMedications(accessor);
             HealthVaultPlatformItem.DisableMock(mock);
 
             Assert.AreEqual(2, newItems.Count);
             Assert.AreEqual("Ibuprofen" , ((Medication)newItems[0]).Name.Text);
             Assert.AreEqual("Vitamin C" , ((Medication)newItems[1]).Name.Text);
         }
 
     {
         HealthRecordItemCollection _itemsToReturn;
 
         public  HealthVaultPlatformItemMock(params  HealthRecordItem[] items)
         {
             _itemsToReturn = new  HealthRecordItemCollection(items);
         }
 
         public  override  ReadOnlyCollection <HealthRecordItemCollection> GetMatchingItems(
             ApplicationConnection connection, 
             HealthRecordAccessor accessor, 
             HealthRecordSearcher searcher)
         {
             List <HealthRecordItemCollection> collections = new  List <HealthRecordItemCollection>();
             collections.Add(_itemsToReturn);
 
             return  new  ReadOnlyCollection <HealthRecordItemCollection>(collections);
         }
     }
 
 
             return  items;
         }
 

Category: Data | Other Posts: View all posts by this blogger | Report as irrelevant | View bloggers stats | Views: 423 | Hits: 3

Similar Posts

  • Using VSTS to Quickly Test Scenarios with Add-In Applications more
  • Telerik Introduces Free Web Testing Framework for ASP.NET AJAX and Silverlight more
  • Introduction to HealthVault Development #3: Configuring our application more
  • Testing RadControls for ASP.NET Ajax with Watir - How easy it is more
  • Six New Videos on ASP.NET Dynamic Data more
  • Getting Started with TDD more
  • Building The Lounge - Release 1.1 - Refactoring, Models, SubSonic, and Testing more
  • Sleep tight, don't let the test bugs bite more
  • My First IronRuby Unit Test Spec For ASP.NET MVC more
  • The Ajax Papers: Part III more

News Categories

.NET | Agile | Ajax | Architecture | ASP.NET | BizTalk | C# | Certification | Data | DataGrid | DataSet | Debugger | DotNetNuke | Events | GridView | IIS | Indigo | JavaScript | Mobile | Mono | Patterns and Practices | Performance | Podcast | Refactor | Regex | Security | Sharepoint | Silverlight | Smart Client Applications | Software | SQL | VB.NET | Visual Studio | W3 | WCF | WinFx | WPF | WSE | XAML | XLinq | XML | XSD