diff --git a/System.IO.Abstractions.TestingHelpers.Tests/MockFileStreamTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/MockFileStreamTests.cs index 214248910..dc8c2d96a 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/MockFileStreamTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/MockFileStreamTests.cs @@ -57,5 +57,22 @@ public void MockFileStream_Constructor_Reading_Nonexistent_File_Throws_Exception // Assert - expect an exception } + + [Test] + public void MockFileStream_Constructor_ReadTypeNotWritable() + { + // Arrange + var filePath = @"C:\test.txt"; + var fileSystem = new MockFileSystem(new Dictionary + { + { filePath, new MockFileData("hi") } + }); + + // Act + var stream = new MockFileStream(fileSystem, filePath, MockFileStream.StreamType.READ); + + Assert.IsFalse(stream.CanWrite); + Assert.Throws(() => stream.WriteByte(1)); + } } } diff --git a/System.IO.Abstractions.TestingHelpers.Tests/MockFileTests.cs b/System.IO.Abstractions.TestingHelpers.Tests/MockFileTests.cs index 86174dcaf..2468c9824 100644 --- a/System.IO.Abstractions.TestingHelpers.Tests/MockFileTests.cs +++ b/System.IO.Abstractions.TestingHelpers.Tests/MockFileTests.cs @@ -413,6 +413,7 @@ public void MockFile_OpenWrite_ShouldCreateNewFiles() { string filePath = XFS.Path(@"c:\something\demo.txt"); string fileContent = "this is some content"; var fileSystem = new MockFileSystem(); + fileSystem.AddDirectory(XFS.Path(@"c:\something")); var bytes = new UTF8Encoding(true).GetBytes(fileContent); var stream = fileSystem.File.OpenWrite(filePath); @@ -423,6 +424,15 @@ public void MockFile_OpenWrite_ShouldCreateNewFiles() { Assert.That(fileSystem.GetFile(filePath).TextContents, Is.EqualTo(fileContent)); } + [Test] + public void MockFile_OpenWrite_ShouldNotCreateFolders() + { + string filePath = XFS.Path(@"c:\something\demo.txt"); // c:\something does not exist: OpenWrite should fail + var fileSystem = new MockFileSystem(); + + Assert.Throws(() => fileSystem.File.OpenWrite(filePath)); + } + [Test] public void MockFile_OpenWrite_ShouldOverwriteExistingFiles() { @@ -667,6 +677,26 @@ public void MockFile_Replace_ShouldThrowIfDestinationFileDoesNotExist() Assert.Throws(() => fileSystem.File.Replace(path1, path2, null)); } + + [Test] + public void MockFile_OpenRead_ShouldReturnReadOnlyStream() + { + // Tests issue #230 + // Arrange + string filePath = XFS.Path(@"c:\something\demo.txt"); + string startContent = "hi there"; + var fileSystem = new MockFileSystem(new Dictionary + { + { filePath, new MockFileData(startContent) } + }); + + // Act + var stream = fileSystem.File.OpenRead(filePath); + + // Assert + Assert.IsFalse(stream.CanWrite); + Assert.Throws(() => stream.WriteByte(0)); + } #endif } } diff --git a/System.IO.Abstractions.TestingHelpers/MockFile.cs b/System.IO.Abstractions.TestingHelpers/MockFile.cs index 64e9b4d23..0b02bcc88 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFile.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFile.cs @@ -399,12 +399,14 @@ public override Stream Open(string path, FileMode mode, FileAccess access, FileS } var length = mockFileDataAccessor.GetFile(path).Contents.Length; - var stream = OpenWrite(path); - - if (mode == FileMode.Append) - stream.Seek(length, SeekOrigin.Begin); + + MockFileStream.StreamType streamType = MockFileStream.StreamType.WRITE; + if (access == FileAccess.Read) + streamType = MockFileStream.StreamType.READ; + else if (mode == FileMode.Append) + streamType = MockFileStream.StreamType.APPEND; - return stream; + return new MockFileStream(mockFileDataAccessor, path, streamType); } public override Stream OpenRead(string path) @@ -426,7 +428,7 @@ public override Stream OpenWrite(string path) { mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path"); - return new MockFileStream(mockFileDataAccessor, path, MockFileStream.StreamType.WRITE); + return Open(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None); } public override byte[] ReadAllBytes(string path) diff --git a/System.IO.Abstractions.TestingHelpers/MockFileStream.cs b/System.IO.Abstractions.TestingHelpers/MockFileStream.cs index f455c7fec..2482ae1c2 100644 --- a/System.IO.Abstractions.TestingHelpers/MockFileStream.cs +++ b/System.IO.Abstractions.TestingHelpers/MockFileStream.cs @@ -5,6 +5,7 @@ public class MockFileStream : MemoryStream { private readonly IMockFileDataAccessor mockFileDataAccessor; private readonly string path; + private readonly bool canWrite = true; public enum StreamType { @@ -38,8 +39,12 @@ public MockFileStream(IMockFileDataAccessor mockFileDataAccessor, string path, S } mockFileDataAccessor.AddFile(path, new MockFileData(new byte[] { })); } + + canWrite = streamType != StreamType.READ; } + public override bool CanWrite => canWrite; + #if NET40 public override void Close() {