Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从物理文件实例化文件_C#_Asp.net_Unit Testing_Asp.net Core - Fatal编程技术网

C# 从物理文件实例化文件

C# 从物理文件实例化文件,c#,asp.net,unit-testing,asp.net-core,C#,Asp.net,Unit Testing,Asp.net Core,我有一个物理文件,我想将它传递给我的控制器方法,该方法需要ifformfile类型(用于单元测试) 我找不到任何实例化ifformfile接口的类,这意味着我无法创建一个类 如何将物理文件转换为ifformfile?假设您有一个接受ifforminfo的控制器方法 [HttpPost] public Task<IActionResult> Upload(IFormFile file) { FileDetails fileDetails = null; using (

我有一个物理文件,我想将它传递给我的控制器方法,该方法需要
ifformfile
类型(用于单元测试)

我找不到任何实例化
ifformfile
接口的类,这意味着我无法创建一个类


如何将物理文件转换为
ifformfile

假设您有一个接受
ifforminfo
的控制器方法

[HttpPost]
public Task<IActionResult> Upload(IFormFile file) {

    FileDetails fileDetails = null;
    using (var reader = new StreamReader(file.OpenReadStream())) {
        var fileContent = reader.ReadToEnd();
        ContentDispositionHeaderValue parsedContentDisposition = null;
        if (ContentDispositionHeaderValue.TryParse(file.ContentDisposition, out parsedContentDisposition)) {
            fileDetails = new FileDetails {
                Filename = parsedContentDisposition.FileName,
                Content = fileContent
            };
        }
    }

    return Task.FromResult((IActionResult)fileDetails);

}
模拟的排列甚至可以提取为可重用的扩展方法

public static IFormFile AsMockIFormFile(this FileInfo physicalFile) {
    var fileMock = new Mock<IFormFile>();
    var ms = new MemoryStream();
    var writer = new StreamWriter(ms);
    writer.Write(physicalFile.OpenRead());
    writer.Flush();
    ms.Position = 0;
    var fileName = physicalFile.Name;
    //Setup mock file using info from physical file
    fileMock.Setup(_ => _.FileName).Returns(fileName);
    fileMock.Setup(_ => _.Length).Returns(ms.Length);
    fileMock.Setup(m => m.OpenReadStream()).Returns(ms);
    fileMock.Setup(m => m.ContentDisposition).Returns(string.Format("inline; filename={0}", fileName));
    //...setup other members (code removed for brevity)


    return fileMock.Object;
}
您可以实例化一个。它实现了
格式文件

.Net Core 3.1中的示例(假设“文件”是物理路径和文件):

我尝试了Nkosi的答案(使用.NETCore3.1),但它只会返回“System.IO.FileStream”作为文件内容!可能是因为它正在将FileStream对象从physicalFile.OpenRead()写入输出流,而不是流的实际内容。这个修改过的版本适合我:

    public static IFormFile AsMockIFormFile(this FileInfo physicalFile)
    {
        var fileMock = new Mock<IFormFile>();
        var ms = new MemoryStream();
        var writer = new StreamWriter(ms);
        using (FileStream fs = physicalFile.OpenRead())
        {
            byte[] b = new byte[1024];
            UTF8Encoding temp = new UTF8Encoding(true);

            while (fs.Read(b, 0, b.Length) > 0)
            {
                writer.WriteLine(temp.GetString(b));
            }
        }
        writer.Flush();
        ms.Position = 0;
        var fileName = physicalFile.Name;
        //Setup mock file using info from physical file
        fileMock.Setup(_ => _.FileName).Returns(fileName);
        fileMock.Setup(_ => _.Length).Returns(ms.Length);
        fileMock.Setup(m => m.OpenReadStream()).Returns(ms);
        fileMock.Setup(m => m.ContentDisposition).Returns(string.Format("inline; filename={0}", fileName));
        //...setup other members as needed

        return fileMock.Object;
    }
publicstaticiformfile AsMockIFormFile(此FileInfo物理文件)
{
var fileMock=new Mock();
var ms=新内存流();
var writer=新的StreamWriter(毫秒);
使用(FileStream fs=physicalFile.OpenRead())
{
字节[]b=新字节[1024];
UTF8Encoding temp=新的UTF8Encoding(真);
而(fs.Read(b,0,b.Length)>0)
{
writer.WriteLine(临时GetString(b));
}
}
writer.Flush();
ms.Position=0;
var fileName=physicalFile.Name;
//使用物理文件中的信息设置模拟文件
fileMock.Setup(=>quot.FileName).Returns(FileName);
fileMock.Setup(=>979;.Length).Returns(ms.Length);
Setup(m=>m.OpenReadStream()).Returns(ms);
Setup(m=>m.ContentDisposition).Returns(string.Format(“inline;filename={0}”,filename));
//…根据需要设置其他成员
返回fileMock.Object;
}

这里有一个,但它位于内部名称空间中,因此您不应该真正使用它。如果这是用于单元测试,则可以模拟接口或实现用于测试目的的自己的类。这看起来没问题,但如果尝试序列化fileMock.Object,则会出现异常我们是否应该使用具有内部名称空间的类?看起来FormFile在.Net Core 2中是内部的,现在已在.Net Core 3+中公开。还要注意,在某些情况下,例如,在使用DocumentFormat.OpenXml包处理文件时,我还必须添加以下行:
physicalFile.IsReadOnly=true
var physicalFile = new FileInfo("filePath");
IFormFile formFile = physicalFile.AsMockIFormFile();
using var stream = new MemoryStream(File.ReadAllBytes(file).ToArray());
var formFile = new FormFile(stream, 0, stream.Length, "streamFile", file.Split(@"\").Last());
    public static IFormFile AsMockIFormFile(this FileInfo physicalFile)
    {
        var fileMock = new Mock<IFormFile>();
        var ms = new MemoryStream();
        var writer = new StreamWriter(ms);
        using (FileStream fs = physicalFile.OpenRead())
        {
            byte[] b = new byte[1024];
            UTF8Encoding temp = new UTF8Encoding(true);

            while (fs.Read(b, 0, b.Length) > 0)
            {
                writer.WriteLine(temp.GetString(b));
            }
        }
        writer.Flush();
        ms.Position = 0;
        var fileName = physicalFile.Name;
        //Setup mock file using info from physical file
        fileMock.Setup(_ => _.FileName).Returns(fileName);
        fileMock.Setup(_ => _.Length).Returns(ms.Length);
        fileMock.Setup(m => m.OpenReadStream()).Returns(ms);
        fileMock.Setup(m => m.ContentDisposition).Returns(string.Format("inline; filename={0}", fileName));
        //...setup other members as needed

        return fileMock.Object;
    }