This library is an alternative testing helper for the IFileSystem interfaces from System.IO.Abstractions.
These interfaces allow abstracting away all I/O-related functionality from the System.IO
namespace.
The testing helper also supports advanced scenarios like
- Multiple drives with limited size
FileSystemWatcher
and- a way to work with SafeFileHandles
The companion projects Testably.Abstractions.Compression and Testably.Abstractions.AccessControl allow working with Zip-Files and Access Control Lists respectively.
As the test suite runs both against the mocked and the real file system, the behaviour between the two is identical.
In addition, the following interfaces are defined:
- The
ITimeSystem
interface abstracts away time-related functionality:DateTime
methods give access to the current timeTask
allows replacingTask.Delay
Thread
allows replacingThread.Sleep
Timer
is a wrapper aroundSystem.Threading.Timer
- The
IRandomSystem
interface abstracts away functionality related to randomness:
Random
methods implement a thread-safe Shared instance also under .NET Framework andGuid
methods allow creating new GUIDs.
Use the interfaces and their default implementations using your prefered dependency injection method, e.g.:
private readonly IFileSystem _fileSystem;
public class MyService(IFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
public void StoreData()
{
var fileContent = GetFileContent();
_fileSystem.File.WriteAllText("result.xml", fileContent);
}
private string GetFileContent()
{
// Generate the file content
}
Then you test your class with the mocked types in Testably.Abstractions.Testing
:
[Fact]
public void StoreData_ShouldWriteValidFile()
{
IFileSystem fileSystem = new MockFileSystem();
MyService sut = new MyService(fileSystem);
sut.StoreData();
var fileContent = fileSystem.File.ReadAllText("result.xml");
// Validate fileContent
}
More examples can be found in the examples section!
-
Install
Testably.Abstractions
as nuget package in your productive projects andTestably.Abstractions.Testing
as nuget package in your test projects.dotnet add package Testably.Abstractions dotnet add package Testably.Abstractions.Testing
-
Configure your dependeny injection framework, e.g. with
Microsoft.Extensions.DependencyInjections
in ASP.NET core:builder.Services .AddSingleton<IFileSystem, RealFileSystem>() .AddSingleton<IRandomSystem, RealRandomSystem>() .AddSingleton<ITimeSystem, RealTimeSystem>();
You can now use the interfaces in your services!
In order to simplify testing, the Testably.Abstractions.Testing
project provides mocked instances for the abstraction interfaces:
These mocks are configured using fluent syntax:
new MockFileSystem()
.WithDrive("D:", d => d
.SetTotalSize(1024 * 1024))
.InitializeIn("D:")
.WithFile("foo.txt")
.WithSubdirectory("sub-dir").Initialized(s => s
.WithAFile(".json").Which(
f => f.HasStringContent("{\"count\":1}")));
Initializes the mocked file system with a second drive D:
with 1MB total available space and creates on it an empty text file foo.txt
and a directory sub-dir
which contains randomly named json file with {"count":1}
as file content.