Unit Testing Windows RT Apps
August 28, 2012 Leave a comment
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.
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.
When I run a unit test against this class library, the same code throws an exception:
It looks like Unit Tests add another layer to the path. Here is the original:
And here is the Tests:
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()