System.IO.Abstractions
System.IO.Abstractions copied to clipboard
fix: Make mocked data lazy-loaded
This moves the initialization of cachedMockFileData to the first time that it is actually used. Apparently, this is more closely to how it works in .NET 6.
Closes #899
@fgreinacher this partly implicitly reverts a change that you made here. In #899, we noticed that the behaviour of FileInfo in .NET 6 is a bit different to the current behaviour of the MockFileSystem. This aligns the mock's behaviour a bit better to CoreCLR, but is probably not perfect, either.
Thinking aloud, now that I have a little more time for this PR:
With this change, we would actually regress in regards to the DirectoryInfo.GetFiles, DirectoryInfo.EnumerateFiles, ...
(see here for details) methods initialization behavior, as those methods no longer return an initalized MockFileInfo.
Remember, before it was automatically initialized by the Refresh() call in MockFileInfo ctor!
Can't we fix this regression by simply calling Refresh in the corresponding MockDirectoryInfo methods, e.g. here
https://github.com/TestableIO/System.IO.Abstractions/blob/main/src/System.IO.Abstractions.TestingHelpers/MockDirectoryInfo.cs#L311-L368
when we are constructing the MockFileInfo object?
We don't have any tests for the "initalize FileInfo when going through these methods", that is why this change in behavior is not caught by the tests, but propably need them. Willing to go the extra mile?
With this change, we would actually regress in regards to the
DirectoryInfo.GetFiles, DirectoryInfo.EnumerateFiles, ...(see here for details) methods initialization behavior, as those methods no longer return an initalized MockFileInfo. Remember, before it was automatically initialized by theRefresh()call in MockFileInfo ctor!
If we're speaking .NET 5's System.IO.DirectoryInfo, I don't think that the FileInfo returned by GetFiles etc. are actually initialized by the framework.
GetFilescallsInternalEnumerateInfosInternalEnumerateInfosreturns a newFileSystemEnumerable<FileInfo>(viaFileSystemEnumerableFactory)FileSystemEnumerable, through a delegate and viaFileSystemEntryreturns aFileSystemInfofrom theCreatemethod- Since that uses the normal
FileInfoconstructor internally, it's not initialized
Sooo … the changed behaviour caused by this PR would be a regression to the current System.IO.Abstractions behaviour, but closer to the current .NET behaviour?
We don't have any tests for the "initalize FileInfo when going through these methods", that is why this change in behavior is not caught by the tests, but propably need them. Willing to go the extra mile?
Therefore, we possibly don't need this?
With this change, we would actually regress in regards to the
DirectoryInfo.GetFiles, DirectoryInfo.EnumerateFiles, ...(see here for details) methods initialization behavior, as those methods no longer return an initalized MockFileInfo. Remember, before it was automatically initialized by theRefresh()call in MockFileInfo ctor!If we're speaking .NET 5's
System.IO.DirectoryInfo, I don't think that theFileInforeturned byGetFilesetc. are actually initialized by the framework.
GetFilescallsInternalEnumerateInfosInternalEnumerateInfosreturns a newFileSystemEnumerable<FileInfo>(viaFileSystemEnumerableFactory)FileSystemEnumerable, through a delegate and viaFileSystemEntryreturns aFileSystemInfofrom theCreatemethod
You need to follow the reading of this method, a few lines below, the FileSystemInfo.Init method is called, see here
https://github.com/dotnet/runtime/blob/13f648fa15c2989455415f4941dad2abfbaa6bba/src/libraries/System.Private.CoreLib/src/System/IO/FileSystemInfo.Windows.cs#L34
To my understanding, this does initialize the cache, following the calls into FileSystemInfo.Init where it sets the _dataInitialized=0