-
Notifications
You must be signed in to change notification settings - Fork 0
Testing
Swap disk for memory — the same code that runs in production against LocalFileHub runs instantly in tests against MemoryFileHub.
Code under test depends on IFileHub / DirectoryEntry, not a driver. Production wires in LocalFileHub; tests wire in MemoryFileHub.
public class ReportService(IFileHub hub)
{
public void Save(string name, string body)
=> hub.Root.CreateFile(name).SetText(body);
}[Fact]
public void Save_writes_content()
{
var hub = new MemoryFileHub();
new ReportService(hub).Save("report.txt", "hello");
Assert.Equal("hello", hub.Root.OpenFile("report.txt").ReadAllText());
}No temp directory, no teardown. Fresh hub per test.
var hub = new MemoryFileHub();
hub.Root.CreateDirectory("inbox")
.CreateFile("20260101.json").SetText("{\"id\":1}");
new InboxProcessor(hub).ProcessAll();
Assert.False(hub.Root.OpenDirectory("inbox").FileExists("20260101.json"));
Assert.True (hub.Root.OpenDirectory("processed").FileExists("20260101.json"));Let the system under test own its state — capturing the root from the DI factory gives you a handle to a different tree than the SUT constructs.
// ✅ resolve from the container
services.AddFileHub<IMemoryFileHub>(_ => new MemoryFileHub());
var provider = services.BuildServiceProvider();
var hub = provider.GetRequiredService<IMemoryFileHub>();
/* run SUT */
Assert.True(hub.Root.FileExists("report.txt"));For code that shells out to a real process, point LocalFileHub at a per-test temp directory:
var tmp = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"));
try
{
var hub = new LocalFileHub(tmp);
/* ... */
}
finally { Directory.Delete(tmp, recursive: true); }Wrap the hub before passing it to code that must not mutate — the test fails fast if the contract is broken.
var ro = hub.Root.OpenDirectory("config").AsReadOnly();
new ReadOnlyConsumer(ro); // any CreateFile/Delete/Rename would throwMock your own service instead. If you need to exercise code that depends on IOracleObjectStorageFileHub, route it through IFileHub and inject a MemoryFileHub — the driver's own tests use a private IOciClient fake that is not meant to be reused externally.
- New
MemoryFileHubper test. No shared state. -
Exists()after every mutation is the canonical presence assertion. -
GetFiles/GetDirectoriesorder is not guaranteed — don't depend on it. - Every async method takes a
CancellationToken— wire up test cancellation where useful.
FileHub — unified file & directory API for .NET. Core is dependency-free; drivers are opt-in packages.