简体   繁体   English

测试 .net 内核 web api Z594C103F2C6E04C3D8AB059F031E0C 使用 XUnitCoreTestHost 文件上传。

[英]Testing a .net core web api controller file upload using XUnit and AspNetCore.TestHost

I have this controller to upload files:我有这个 controller 来上传文件:

[HttpPost]
public async Task<IActionResult> Post([FromForm] FileInformation fileInfo)
{
    int newFileVersion = 1;

    if (fileInfo == null || fileInfo.Files == null || fileInfo.Files.Count == 0)
        return BadRequest("File(s) not found");

    try
    {
        foreach (var locFile in fileInfo.Files)
        {
            //check for file extension, if not there, return an error
            var fileExtension = Path.GetExtension(locFile.FileName);
            if (string.IsNullOrEmpty(fileExtension))
                return BadRequest("Files must include file extension");


            var valid = await fileUtilities.IsFileValid(locFile);

            var newFileName = string.Concat(Guid.NewGuid().ToString(),valid.fileExtension);

            var newFileLocation = Path.Combine(config.GetSection("StoredFilePath").Value, newFileName);
           

            if (!valid.FileExtensionFound)
            {
                return BadRequest($"Error {valid.FileExtensionFoundError}");
            }
            if (!valid.FileSizeAllowed)
            {
                return BadRequest($"Error: {valid.FileSizeAllowedError}");
            }


            //check for an existing file in the database.  If there is one, increment the file version before the save
            var currentFile = await fileUtilities.FileExists(fileInfo, locFile);

            if (currentFile != null)
            {
                newFileVersion = currentFile.Version + 1;
            }
      
            //save to the file system
            using (var stream = new FileStream(newFileLocation, FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                await locFile.CopyToAsync(stream);
            }

            //save to the db.  Check to see if the file exists first.  If it does, do an insert, if not, return an error
            if (System.IO.File.Exists(newFileLocation))
            {
                FileUploads upload = new FileUploads
                {
                    EntityId = fileInfo.EntityId,
                    FileName = locFile.FileName,
                    ItemId = fileInfo.ItemId.ToString(),
                    NewFileName = newFileName,
                    ValidFile = true,
                    Version = newFileVersion
                };
                context.FileUploads.Add(upload);
                context.SaveChanges();
                //TODO: fire event the file has been saved provide Id key to find the record
                //upload.Id;
            }
            else
            {
                return BadRequest("Error: File Could not be saved");
            }

        }
    }
    catch (Exception ex)
    {
        return BadRequest("Failure to upload files.");
    }
    return Ok("File Uploaded");
}

I am trying to write a unit text using XUnit and the Microsoft.AspNetCore.TestHost and I can't figure out how to write the test for the file upload.我正在尝试使用 XUnit 和Microsoft.AspNetCore.TestHost编写单元文本,但我不知道如何编写文件上传测试。 Here is one test I'm using to get a badrequest:这是我用来获取错误请求的一项测试:

[Theory]
[InlineData("POST", "")]
public async Task LibrarianUploadFile_Error(string method, string? data = null)
{
    //arrange
    var request = new HttpRequestMessage(new HttpMethod(method), $"/api/librarian");

    //act
    var response = await _client.SendAsync(request);

    //assert
    Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
}

This test is passing.这个测试通过了。 I have written all the other test for the GET methods without a problem, I just don't know how to do this test.我已经为 GET 方法编写了所有其他测试,没有问题,我只是不知道如何进行此测试。 I was thinking I could have a test file on my local test machine to upload, I just don't know how to construct the POST.我在想我可以在我的本地测试机器上上传一个测试文件,我只是不知道如何构建 POST。

Here is the my constructor for the Class:这是我的 Class 的构造函数:

private readonly HttpClient _client;

public LibrarianUploadFiles()
{
    var configuration = new ConfigurationBuilder()
       .AddJsonFile("appsettings.json")
       .Build();

    var server = new TestServer(new WebHostBuilder()
        .UseConfiguration(configuration)
        .UseStartup<Startup>());
    _client = server.CreateClient();
}

This creates the client I need to GET, POST, etc.这将创建我需要 GET、POST 等的客户端。

Here is the final solution to the problem.这是问题的最终解决方案。 Using the answer from @gpaoli and a little looking around I got this code to post and pass the test.使用@gpaoli 的答案并环顾四周,我得到了这段代码来发布并通过测试。

 //arrange
        var request = new HttpRequestMessage(new HttpMethod(method), [url to post]);

        using var form = new MultipartFormDataContent();
        using var fileContent = new ByteArrayContent(await File.ReadAllBytesAsync(@"c:\files\test.txt"));
        fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
        form.Add(fileContent, "Files", "test.txt");
        form.Add(new StringContent("Partner1"), "EntityId");
        form.Add(new StringContent(Guid.NewGuid().ToString()), "ItemId");

        //act
        HttpResponseMessage response;
        
        response = await _client.PostAsync($"/api/librarian", form);

        //assert

        Assert.Equal(HttpStatusCode.OK, response.StatusCode);

Couple of problems I had was adding the stringContent and making sure that the File, and string content was named correctly so the controller could map the values.我遇到的几个问题是添加 stringContent 并确保正确命名文件和字符串内容,以便 controller 可以 map 值。

Do you need make post similar this:您是否需要发布类似的帖子:

// Act
HttpResponseMessage response;

using (var file = File.OpenRead(@"path\fileName.txt"))
using (var content = new StreamContent(file))
using (var formData = new MultipartFormDataContent())
{
    formData.Add(content, "fileInfo", "fileName.txt");

    response = await client.PostAsync(url, formData);
}

// Assert
response.EnsureSuccessStatusCode(); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 依赖项注入不适用于ASPNETCore.TestHost - Dependancy Injection not working with ASPNETCore.TestHost .net Core中控制器的XUnit测试时间错误 - Error in time XUnit testing of the controller in .net Core 将 Moq 与 Xunit 一起使用 - 单元测试 .net 核心 API - Using Moq with Xunit - Unit testing .net core API ASP .NET Core Web API - Getting and extracting a.zip file from upload controller, using IFormFile - ASP .NET Core Web API - Getting and extracting a .zip file from upload controller, using IFormFile 使用ClientWebSocket .net核心测试TestHost.WebSocketClient - Testing TestHost.WebSocketClient with ClientWebSocket .net core xunit 测试 web api 2 控制器:抛出 Xunit.Sdk.IsTypeException - xunit testing web api 2 controller : throws Xunit.Sdk.IsTypeException 如何使用WEB API Dot net core实现文件上传? - How to achieve File upload using WEB API Dot net core? 从angular上传文件到asp.net核心web api controller - Upload file from angular to asp.net core web api controller 用TestHost测试AspNetCore,找不到WebApplicationTestFixture类 - AspNetCore testing with TestHost, WebApplicationTestFixture class not found .Net Core 5 Web Api - Xunit 不读取我的 appsettings.Development - .Net Core 5 Web Api - Xunit not reading my appsettings.Development
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM