How to write a test that checks for insufficient space available?
Describe the bug I need to write a test for some logic that checks if there is enough space available on disk.
To Reproduce
logic to test
private IFileSystem _fileSystem;//injected in ctor as = new MockFileSystem() in tests | = new FileSystem() in production
var requiredSpace = calculateActualSize(filePaths);
var availableFreeSpace = getAvailableFreeSpaceOnDisk(driveName);
if (availableFreeSpace < requiredSpace)
{
//throw exception
}
private long getAvailableFreeSpaceOnDisk(string driveName)
{
var driveInfo = _fileSystem.DriveInfo.FromDriveName(driveName);
var result = driveInfo.AvailableFreeSpace;
return result;
}
test code so far (does not work)
[Fact]
public void RequiredSpaceIsInsufficient_ShouldThrow()
{
// Arrange
var fileSystem = new MockFileSystem();
fileSystem.AddDirectory(@"Q:\Destination");
fileSystem.AddFile(@"W:\source\test.txt", new MockFileData(new byte[2]));
var driveInfo = new MockDriveInfo(fileSystem, "Q");
driveInfo.AvailableFreeSpace = 1;
// Act
var ex = Record.Exception(() => new ClassToTest(fileSystem).MethodToTest());
// Assert
Assert.IsType<ExpectedExceptionType>(ex);
}
Actual behavior
The injected IFileSystem has a DriveInfo with AvailableFreeSpace set to 0.
Expected behavior
The injected IFileSystem has a DriveInfo with AvailableFreeSpace set to 1.
Additional context I did some search and found a comment on issue #274, but I'm still unable to understand how to write a functioning test.
This is currently not possible. As mentioned in the issue you linked these properties should actually be read-only.
Would be cool to support this somehow, but I guess it would be quite some effort. I will probably not find the time for implementing this anytime soon, but would be open for a contribution.
Thank you for your time and your reply.
In the meantime I managed to come up with a workaround.
I made my own IFileSystem by inheriting from MockFileSystem and used Moq. Maybe it is useful for someone else.
public class TestClass
{
[Fact]
public void CreateBackup_RequiredSpaceIsInsufficient_ShouldReturnFalse()
{
// Arrange
var sourceFilePath = $@"A:\source\test.txt";
var fileSize = 2;
//setup DriveInfo for backup
var mockedDriveInfo = new Mock<IDriveInfo>();
mockedDriveInfo.Setup(x => x.Name).Returns(() => "Q");
mockedDriveInfo.Setup(x => x.AvailableFreeSpace).Returns(() => fileSize - 1);
var mockedDriveInfoFactory = new Mock<IDriveInfoFactory>();
mockedDriveInfoFactory.Setup(x => x.FromDriveName(It.IsAny<string>())).Returns(() => mockedDriveInfo.Object);
//add files to backup to FileSystem
var fileSystem = new MyMockFileSystem(mockedDriveInfoFactory.Object);
fileSystem.AddFile(sourceFilePath, new MockFileData(new byte[fileSize]));
// ...
}
}
internal class MyMockFileSystem : MockFileSystem
{
private IDriveInfoFactory _driveInfoFactory;
public MyMockFileSystem(IDriveInfoFactory driveInfoFactoryToUse) : base()
{
_driveInfoFactory = driveInfoFactoryToUse;
}
public override IDriveInfoFactory DriveInfo => _driveInfoFactory;
}
In the meantime I managed to come up with a workaround. I made my own
IFileSystemby inheriting fromMockFileSystemand usedMoq. Maybe it is useful for someone else.
Thanks for sharing your solution, looks neat to me!
This is addressed in release v20.0.28.