Unit Testing Windows RT Apps

I started building some Unit Tests for a windows RT application and I ran into 2 gotchas. 

#1) The file system moves in a test

Well, not really.  But consider this desktop application.  There is a folder called LookupData with an .xml file in it.

clip_image001

I wrote some code that accesses this file via the desktop application and it runs fine:

private async void Button_Click_1(object sender, RoutedEventArgs e)

{

StorageFolder storageFolder = await Package.Current.InstalledLocation.GetFolderAsync("LookupData");

StorageFile storageFile = await storageFolder.GetFileAsync("ObjectiveType.xml");

XmlDocument xmlDocument = await XmlDocument.LoadFromFileAsync(storageFile);

Debug.WriteLine(xmlDocument.InnerText);

}

I then crated a class library that access the same file.

clip_image002

When I run a unit test against this class library, the same code throws an exception:

clip_image003

It looks like Unit Tests add another layer to the path.  Here is the original:

clip_image004

And here is the Tests:

clip_image005

I am guessing MSFT will say that I should be using a Mocking Framework.  The problem is that if I want to do integration tests, I can’t.  Sigh!

#2) You need to make sure all of your tests are async and return a Tasks if they call a async method

I figured out my path problem when I ran into another problem.  I have this set of code wired up:

public async Task LoadFromXML(String path)
{
ObjectiveTypes = new List<ObjectiveType>();
StorageFile storageFile = await StorageFile.GetFileFromPathAsync(path);
XmlDocument xmlDocument = await XmlDocument.LoadFromFileAsync(storageFile);
XDocument xDocument = XDocument.Parse(xmlDocument.GetXml());
var data = from ot in xDocument.Descendants("ObjectiveType")
select ot;
ObjectiveType objectiveType = null;
foreach (var d in data)
{
objectiveType = new ObjectiveType();
objectiveType.ObjectiveTypeId = (Int32)d.Element("ObjectiveTypeId");
objectiveType.ObjectiveTypeDescription = (String)d.Element("ObjectiveTypeDescription");
ObjectiveTypes.Add(objectiveType);
}
}

To unit test, I wrote the following code

[TestMethod]
public void LoadObjectiveTypeFromXML_LoadsSuccessfully_Test()
{
CampaignVictoryConditionFactory factory = new CampaignVictoryConditionFactory();
StorageFolder storageFolder = Package.Current.InstalledLocation;
String path = storageFolder.Path + @"\Tff.Core\LookupData\VictoryCondition_Campaign.xml";
await factory.LoadFromXML(path);
int notExpected = 0;
int actual = factory.CampaignVictoryConditions.Count;
Assert.AreNotEqual(notExpected, actual);
}

But then I get the compiler complaining:

Error 1 The ‘await’ operator can only be used within an async method. Consider marking this method with the ‘async’ modifier and changing its return type to ‘Task’.

I then changed the test’s signature and it ran:

public async Task LoadObjectiveTypeFromXML_LoadsSuccessfully_Test()
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: