Skip to main content

FileSystemWatcher

MockFileSystem ships a fully functional FileSystemWatcher replacement. It fires the same events as the real one and, crucially, it fires the OS-specific events that the real watcher fires on Linux, Windows and macOS.

Basic usage​

MockFileSystem fileSystem = new();
fileSystem.Initialize().WithSubdirectory("vault");
fileSystem.File.WriteAllBytes("vault/red-square.png", []);

using IFileSystemWatcher watcher = fileSystem.FileSystemWatcher.New("vault");
ManualResetEventSlim artworkRemoved = new();

watcher.Deleted += (_, _) => artworkRemoved.Set();
watcher.EnableRaisingEvents = true;

fileSystem.File.Delete("vault/red-square.png");

await That(artworkRemoved.Wait(TimeSpan.FromSeconds(1))).IsTrue();

Reacting to triggered events from a test​

MockFileSystem.Watcher.OnTriggered(...) returns an awaitable callback that fires after every IFileSystemWatcher event. Use it to assert what a watcher saw without subscribing to the event yourself:

MockFileSystem fileSystem = new();
fileSystem.Initialize().WithSubdirectory("vault");

using IFileSystemWatcher watcher = fileSystem.FileSystemWatcher.New("vault");
watcher.EnableRaisingEvents = true;

using IAwaitableCallback<WatcherChangeDescription> triggered = fileSystem.Watcher.OnTriggered();

fileSystem.File.WriteAllBytes("vault/blue-circles.png", []);
WatcherChangeDescription[] events = triggered.Wait(count: 1);

Which events are raised​

When an entry is moved, the events depend on where it comes from and where it goes, relative to the watched path:

storage/ ← Outside
vault/ ← the watched path
├── red-square.png ← Inside
└── sketches/
├── blue-circles.png ← Nested
└── drafts/
└── yellow-lines.png ← Deep

_ stands for "nothing", i.e. the entry is created (_ → Inside) or deleted (Inside → _), and - means no event is raised. Pick the value of IncludeSubdirectories:

From → ToLinuxWindowsmacOS
_ → InsideCreatedCreatedCreated
Inside → _DeletedDeletedDeleted
_ → Nested---
Nested → _---
_ → Deep---
Deep → _---
Outside → InsideCreatedCreatedCreated
Inside → InsideRenamedRenamedRenamed
Inside → OutsideDeletedDeletedDeleted
Outside → Nested---
Nested → Nested---
Nested → Outside---
Outside → Deep---
Deep → Deep---
Deep → Outside---
Inside → NestedDeletedDeletedRenamed
Inside → DeepDeletedDeletedRenamed
Nested → InsideCreatedCreatedCreated
Deep → InsideCreatedCreatedCreated
Nested → Deep---
Deep → Nested---

The mock follows the host OS, or the OS chosen with SimulatingOperatingSystem.