Jacob Tobiasz
Jacob Tobiasz

Reputation: 458

System.IO.Abstraction.TestingHelpers - testing on the different platforms

I'm writing a unit test to check some methods operating on the files. I've used System.IO.Abstraction on the library side, and System.IO.Abstraction.UnitTesting on the UnitTests side.

I'm using MacOS, but I want to be able to run tests on the Windows too. The problem is around paths because as we know on windows it's like "C:\MyDir\MyFile.pdf", but for Linux/MacOS it's more like "/c/MyDir/MyFile.pdf".

var fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
{
    { @"/c/scans/myfile.pdf", new MockFileData("Some text") },
    { @"/c/scans/mysecondfile.pdf", new MockFileData("Some text") },
    { @"/c/scans/mydog.jpg", new MockFileData("Some text") }
});
var fileService = new FileService(fileSystem);
var scanDirPath = @"/c/scans/";

I don't know exactly how to deal with this thing. I'm wondering about setting the "initial" path in the constructor of the xunit tests depending on the platform, but I'm not sure if it's a good practice.

Upvotes: 6

Views: 2096

Answers (2)

0xced
0xced

Reputation: 26538

The System.IO.Abstractions.TestingHelpers package provides a MockUnixSupport class for this purpose.

Here's the recommended usage (from TestableIO.System.IO.Abstractions.TestingHelpers own tests):

using XFS = System.IO.Abstractions.TestingHelpers.MockUnixSupport;

var path = XFS.Path(@"c:\something\demo.txt");

And here's what it would look like for your sample code:

using XFS = System.IO.Abstractions.TestingHelpers.MockUnixSupport;

var fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
{
    { XFS.Path(@"c:\scans\myfile.pdf"), new MockFileData("Some text") },
    { XFS.Path(@"c:\scans\mysecondfile.pdf"), new MockFileData("Some text") },
    { XFS.Path(@"c:\scans\mydog.jpg"), new MockFileData("Some text") }
});
var fileService = new FileService(fileSystem);
var scanDirPath = XFS.Path(@"c:\scans\");

Then you can write your tests without any conditional code.

Upvotes: 2

Lauren Van Sloun
Lauren Van Sloun

Reputation: 1265

I encountered the same scenario where I needed to execute a unit test with the System.IO.Abstraction.TestingHelpers's MockFileSystem on both Windows and Linux. I got it working by adding a check for the platform and then using the expected string format for that platform.

Following the same logic, your tests might look like this:

[Theory]
[InlineData(@"c:\scans\myfile.pdf", @"/c/scans/myfile.pdf")]
[InlineData(@"c:\scans\mysecondfile.pdf", @"/c/scans/mysecondfile.pdf")]
[InlineData(@"c:\scans\mydog.jpg", @"/c/scans/mydog.jpg")]
public void TestName(string windowsFilepath, string macFilepath)
{
    // Requires a using statement for System.Runtime.InteropServices;
    bool isExecutingOnWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); 
    bool isExecutingOnMacOS = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
    
    MockFileSystem fileSystem;
    if (isExecutingOnWindows)
    {
        fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
        {
            { windowsFilepath, new MockFileData("Some text") }
        };
    }
    else if (isExecutingOnMacOS)
    {
        fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
        {
            { macFilepath, new MockFileData("Some text") }
        };
    }
    else
    {
        // Throw an exception or handle this however you choose
    }

    var fileService = new FileService(fileSystem);
    // Test logic...
}

Upvotes: 3

Related Questions