Skip to main content

Getting started

Requirements​

.NET Standard 2.0 or later

The packages target .NET Standard 2.0 and 2.1, .NET 6, .NET 8, .NET 9 and .NET 10, so they also work in .NET Framework projects. Some members are only available on newer target frameworks; the pages that describe them say so.

Install the packages​

Install Testably.Abstractions in your production projects:

dotnet add package Testably.Abstractions

Latest version: 10.4.0

and Testably.Abstractions.Testing in your test projects:

dotnet add package Testably.Abstractions.Testing

Latest version: 7.2.0

PackageInstall it in
Testably.AbstractionsProduction code: contains RealFileSystem, RealTimeSystem and RealRandomSystem
Testably.Abstractions.TestingTest projects: contains MockFileSystem, MockTimeSystem and MockRandomSystem
Testably.Abstractions.InterfaceLibraries that only consume IFileSystem, ITimeSystem or IRandomSystem and leave the choice of implementation to the application
Testably.Abstractions.FileSystem.InterfaceLibraries that only need IFileSystem

Both Testably.Abstractions and Testably.Abstractions.Testing pull in the interface packages transitively.

Optional companion packages add compression, access control and memory-mapped files; each page shows how to install it.

Register the abstractions​

With Microsoft.Extensions.DependencyInjection:

Program.cs
builder.Services
.AddSingleton<IFileSystem, RealFileSystem>()
.AddSingleton<IRandomSystem, RealRandomSystem>()
.AddSingleton<ITimeSystem, RealTimeSystem>();

Use the interfaces in your services​

CatalogService.cs
public class CatalogService(IFileSystem fileSystem)
{
public void Export(string json)
{
fileSystem.Directory.CreateDirectory("exports");
fileSystem.File.WriteAllText("exports/catalog.json", json);
}
}

Write your first test​

In the test, replace the real implementation with the mock:

CatalogServiceTests.cs
using Testably.Abstractions.Testing;
using static aweXpect.Expect;

public class CatalogServiceTests
{
[Test]
public async Task Export_ShouldWriteCatalogToExportsFolder()
{
MockFileSystem fileSystem = new();
CatalogService sut = new(fileSystem);

sut.Export("""{ "title": "Red Square" }""");

await That(fileSystem.File.ReadAllText("exports/catalog.json"))
.IsEqualTo("""{ "title": "Red Square" }""");
}
}

That's it: your code now runs against an in-memory file system in tests, and against the real one in production.

About the examples

The examples in this documentation are set in a gallery of abstract art: a catalog of artworks, exhibitions that open and close, and a night guard on patrol. They use TUnit and check results with aweXpect. Neither is required: the mocks work with any test framework and assertion library.

Next steps​

  • A complete example: one gallery service tested with the file system, time and random system together.
  • File system: IFileSystem, MockFileSystem, drives, watcher, statistics, strategies.
  • Time system: ITimeSystem, time providers, timers, auto-advance, notifications.
  • Random system: IRandomSystem and deterministic generators.
  • Companion libraries: Compression, AccessControl and MemoryMappedFiles.
  • aweXpect.Testably: expectations for the file system and time system mocks, if you use aweXpect.