[英]Throw UnauthorizedAccessException from System.IO.Abstractions
I'm using System.IO.Abstractions
( https://github.com/System-IO-Abstractions ) to allow me to inject an IFileSystem
into my class.我正在使用System.IO.Abstractions
( https://github.com/System-IO-Abstractions ) 来允许我将IFileSystem
注入我的班级。 I've recently added a piece of code to catch an UnauthorizedAccessException
thrown when the user tries to create a file in a directory which they don't have write access to.我最近添加了一段代码来捕获当用户尝试在他们没有写访问权限的目录中创建文件时抛出的UnauthorizedAccessException
。
Is there a way the set the access permissions of a directory within System.IO.Abstractions
?有没有办法在System.IO.Abstractions
设置目录的访问权限?
The following code is as close as I have come ( MockFileSystem
coming from System.IO.Abstractions
).下面的代码和我一样接近( MockFileSystem
来自System.IO.Abstractions
)。 The AccessControlSections
description is AccessControlSections
描述是
Specifies which sections of a security descriptor to save or load指定要保存或加载的安全描述符的哪些部分
So it appears that I need to set up a security descriptor of some sort but I can't find any information on that - or if this is even the right approach.所以看起来我需要设置某种安全描述符,但我找不到任何关于它的信息 - 或者这是否是正确的方法。
var mockFileSystem = new MockFileSystem();
mockFileSystem.Directory.CreateDirectory("C:\\Test", new DirectorySecurity("C:\\Test", AccessControlSections.None));
// This should throw an UnauthorizedAccessException
mockFileSystem.File.Create("C:\\Test\\File.txt");
I tried something like this and failed: 我尝试了类似的操作,但失败了:
const string path = @"C:\temp\incoming";
var fileSystem = new MockFileSystem();
fileSystem.AddDirectory(path);
var diFactory = fileSystem.DirectoryInfo;
var directoryInfo = diFactory.FromDirectoryName(path);
var directorySecurity = directoryInfo.GetAccessControl();
var currentUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
directorySecurity.AddAccessRule(new FileSystemAccessRule(currentUser , FileSystemRights.Read, AccessControlType.Allow));
I still think this is more or less the way to go, unfortunately it doesn't work :-( 我仍然认为这或多或少是要走的路,不幸的是它不起作用:-(
Maybe the user I'm specifying for the AccessRule isn't correct, I've tried with others too but to no avail: 也许我为AccessRule指定的用户不正确,我也尝试了其他用户,但无济于事:
var adminUser = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
// -> Doesn't work either..
Anyway, in the end I created this dirty workaround to test it, and that works obviously: 无论如何,最后我创建了这个肮脏的解决方法来对其进行测试,并且显然可以正常工作:
var mockFileSystem = new Mock<IFileSystem>();
mockFileSystem.Setup(x => x.File.Create(It.IsAny<string>())).Throws(new Exception());
You can create a mock for IFileSystem
to setup the method you wanna throw the exception and then you create a MockFileSystem
to be used only when necessary.您可以为IFileSystem
创建一个模拟来设置您想要抛出异常的方法,然后您创建一个MockFileSystem
仅在必要时使用。 You can setup your mock to return the "real" file system when only some methods are invoked.您可以设置模拟以在仅调用某些方法时返回“真实”文件系统。 In my case bellow, I wanted to only use MockFileSystem
when using the Path
.在我的情况下,我只想在使用Path
时使用MockFileSystem
。
You will have to setup your test like this (please read the comments):您必须像这样设置测试(请阅读评论):
[Fact]
public async void FailWhenCopyFails()
{
// Arrange
var file = Substitute.For<IFile>(); // fake File to throw UnauthorizedAccessException
file
.When(x => x.WriteAllBytesAsync(Arg.Any<string>(), Arg.Any<byte[]>()))
.Do(x => { throw new UnauthorizedAccessException(); });
file.Exists("C:\\Downloads\\" + "eclipse.exe").Returns(true);
var fileSystem = Substitute.For<IFileSystem>(); // fake file system
var mockFileSystem = new MockFileSystem(); // "real" file system to be used only when necessary
fileSystem.File.Returns(file); // pass the File mock which will throw the exception
fileSystem.Path.Returns(mockFileSystem.Path); // the "real" Path is necessary to make the test pass
var httpResponseMessage = new HttpResponseMessage() { StatusCode = HttpStatusCode.OK };
var httpClient = new HttpClient(new MockHttpMessageHandler(httpResponseMessage));
var downloader = new DownloadManager(httpClient, fileSystem);
// Act
await Assert.ThrowsAsync<UnauthorizedAccessException>(() => downloader.DownloadFile(new Uri(eclipseUrl), downloadFolder));
// Assert
downloader.IsSuccess().Should().BeFalse();
}
In my case I wanted to verify the download fails if the http client can't create the downloaded file in the downloads folder (it was supposed to fail if it cannot overwrite the C:\\Downloads\\eclipse.exe already there).在我的情况下,我想验证下载是否失败,如果 http 客户端无法在下载文件夹中创建下载的文件(如果它不能覆盖已经存在的 C:\\Downloads\\eclipse.exe,它应该会失败)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.