Time Tortoise: Using SystemWrapper for Unit Testing, Part 2

Wrapped System

This is one in a series of articles about Time Tortoise, a Universal Windows Platform app for planning and tracking your work schedule. For more on the development of this app and the ideas behind it, see my Time Tortoise category page.

With unit testing and code coverage back up and running after my work of the past two weeks, it’s time to update unit tests to get full coverage of recent functional changes. As I mentioned in an earlier post, the SystemWrapper project provides a starting point for mocking system classes when that is required by unit tests. To best use SystemWrapper, this would be a good time to upgrade Time Tortoise to .NET Standard 2.0.

.NET Standard 2.0

When I did my initial .NET Standard upgrade, UWP only supported .NET Standard 1.4. With the release of the Windows 10 Fall Creators Update, UWP now supports .NET Standard 2.0. This greatly increases the number of APIs available, which means that tools like SystemWrapper that were designed for the full .NET Framework will require fewer changes to work with .NET Core.

Since the Time Tortoise projects were already on .NET Standard, moving to .NET Standard 2.0 was fairly straightforward:

  • In the Project Properties for TimeTortoise.UWP, change both the Min version and Target version to Windows 10 Fall Creators Update (10.0; Build 16299). This means that the app will only be available to users on the most recent version of Windows 10. This reduces the potential user base, but one advantage of developing for Windows 10 is that users are encouraged to rapidly adopt new releases.
  • In the Project Properties for all of the .NET Standard class libraries, change the Target framework from .NET Standard 1.4 to .NET Standard 2.0.
  • In NuGet Package Manager, update all NuGet packages. Some packages have new versions that require .NET Standard 2.0.
  • Rebuild the Time Tortoise solution.

Unit Tests

In a perfect world, the upgrade would be complete after the previous steps. But as I have documented at length: using Visual Studio, .NET Core/.NET Standard, and xUnit.NET requires periodic manual attention to keep things running. So I wasn’t surprised that after the .NET Standard upgrade, none of my .NET Core unit tests were discovered.

Fortunately, I now have a tool that speeds up many of the manual steps required to get unit tests working after dependency changes. Using that tool, I made the DLL updates that were required as a result of the framework upgrade.

SystemWrapper

SystemWrapper targets the traditional .NET Framework 4.x. With the Time Tortoise projects targeting .NET Core 2.0, it should be easier to create a “SystemWrapperCore” that can be referenced from Time Tortoise.

Unfortunately, it’s not as easy as creating a few .NET Core 2.0 projects and copying over the SystemWrapper code. There are still .NET Framework APIs that don’t exist in .NET Core 2.0. So there would be some manual work involved in creating a SystemWrapperCore solution.

Rather than do all of the manual work at once, I have decided to start with an empty project and convert classes as I need them. For example, to write a proper unit test for the Daily Summary File feature, I need a mock version of System.IO.FileInfo. SystemWrapper has the appropriate interface, IFileInfo. That interface references IDirectoryInfo, so I had to add that one as well. But IDirectoryInfo uses System.Runtime.Remoting, which is not available in .NET Core. So I had to comment out the using statement, as well as one method definition, CreateObjRef.

I continued that process with IFileStream, IStream, IStreamReader, IStreamWriter, and a few others, before I got to the point where I could compile my minimal version of SystemWrapper. With luck, I’ll be able to gradually add interfaces without running into an object graph that wants to pull in most of the SystemWrapper solution.

(Image credit: Juhan Sonin)