Repository navigation
Observing changes in the MockFileSystem #805
Copy link
Copy link
Open
Labels
area: testinghelpersIssues that address the testing helpersIssues that address the testing helpersstate: ready to pickIssues that are ready for being worked onIssues that are ready for being worked ontype: enhancementIssues that propose new functionalityIssues that propose new functionality
Description
Activity
- addedstate: needs discussionIssues that need further discussionIssues that need further discussiontype: enhancementIssues that propose new functionalityIssues that propose new functionality
on Feb 3, 2022 This is the same as #168 which has gone stale.
As mentioned over there I generally like the idea and would accept a contribution here unless it's getting overly complex.
- addedarea: testinghelpersIssues that address the testing helpersIssues that address the testing helpersstate: ready to pickIssues that are ready for being worked onIssues that are ready for being worked onand removedstate: needs discussionIssues that need further discussionIssues that need further discussion
on Feb 16, 2022 The neat thing about this kind of approach is that it makes testing certain scenarios easier. For example:
var fileSystem = new MockFileSystem(new MockFileSystemOptions { EnableEvents = true }); // Make everything read-only with one subscription using (fileSystem.Events.Subscribe(args => { if (args.Phase == OperationPhase.Before && (args.Operation == FileOperation.Write || args.Operation == FileOperation.Delete || args.Operation == FileOperation.Create)) { args.SetResponse(new OperationResponse { Exception = new UnauthorizedAccessException("File system is read-only") }); } })) { // This will throw UnauthorizedAccessException fileSystem.File.WriteAllText(@"C:\test.txt", "data"); }
Or generic logging, etc.
var fs = new MockFileSystem(new MockFileSystemOptions { EnableEvents = true }); var log = new List<string>(); using (fs.Events.Subscribe(args => { if (args.Phase == OperationPhase.After) log.Add($"{args.Operation} on {args.Path}"); })) { // Your test code here MyService.ProcessFiles(fs); // Now you can assert on what actually happened Assert.That(log, Contains.Item("Delete on C:\\temp\\cache.tmp")); }
// Simulate disk full on the third write var writeCount = 0; using (fs.Events.Subscribe(FileOperation.Write, args => { if (++writeCount >= 3 && args.Phase == OperationPhase.Before) { args.SetResponse(new OperationResponse { Exception = new IOException("Disk full") }); } })) { // Test your retry logic, error handling, etc. }
// Prevent deletion of important files using (fs.Events.Subscribe(FileOperation.Delete, args => { if (args.Phase == OperationPhase.Before && args.Path.EndsWith(".config")) { args.SetResponse(new OperationResponse { Exception = new UnauthorizedAccessException("Config files are protected") }); } })) { // Deletion is prevented }
The actual syntax to add events is pretty minimal. For example:
return mockFileDataAccessor.Events.WithEvents(fullPath, FileOperation.Read, ResourceType.File, () => { // ... existing code return ReadAllTextInternal(path, encoding); });
Metadata
Metadata
Assignees
Labels
area: testinghelpersIssues that address the testing helpersIssues that address the testing helpersstate: ready to pickIssues that are ready for being worked onIssues that are ready for being worked ontype: enhancementIssues that propose new functionalityIssues that propose new functionality
Describe the solution you'd like
I'd like to be able to observe common/interesting events (from a testing perspective) that happen into a
MockFileSystem.Why? I'm creating a cache service that uses an
IFileSystemand I need to test that a file is only written once.Describe alternatives you've considered
I've tried to implement my own
MockFileSystemusing System.Reactive, but the work is a bit overwhelming.