简体   繁体   中英

Http response headers parser fails when returning FileContentResult in unit test

I'm trying to write unit test for the following AspNetCore controller method:

[HttpGet]
public async Task<IActionResult> GetFile(string id)
{
    FileContent file = await fileRepository.GetFile(id);

    if (file == null)
        return NotFound();

    Response.Headers.Add("Content-Disposition", file.FileName);

    return File(file.File, file.ContentType);
}

FileContent class:

public class FileContent
{
    public FileContent(string fileName, string contentType, byte[] file)
    {
        FileName = fileName;
        ContentType = contentType;
        File = file;
    }

    public string FileName { get; }
    public string ContentType { get; }
    public byte[] File { get; }
}

Here is TestInitialize:

[TestInitialize]
public void TestInitialize()
{
    repositoryMock = new Mock<IFileRepository>();
    controller = new FilesController(repositoryMock.Object);
    var httpContext = new Mock<HttpContext>(MockBehavior.Strict);
    var response = new Mock<HttpResponse>(MockBehavior.Strict);
    var headers = new HeaderDictionary();
    response.Setup(x => x.Headers).Returns(headers);
    httpContext.SetupGet(x => x.Response).Returns(response.Object);
    controller.ControllerContext = new ControllerContext(new ActionContext(httpContext.Object, new RouteData(), new ControllerActionDescriptor()));
}

And test method:

[TestMethod]
public async Task GetShouldReturnCorrectResponse()
{
    repositoryMock
        .Setup(x => x.GetFile(It.IsAny<string>(), null))
        .ReturnsAsync(new FileContent("test.txt", "File Content.", Encoding.UTF8.GetBytes("File Content.")));

    IActionResult response = await controller.GetFile(DocumentId);

    // .. some assertions
}

The test fails on the the following controller line:

return File(file.File, file.ContentType);

The exception:

System.FormatException: The header contains invalid values at index 0: 'File Content.' at Microsoft.Net.Http.Headers.HttpHeaderParser`1.ParseValue(StringSegment value, Int32& index) at Microsoft.AspNetCore.Mvc.FileContentResult..ctor(Byte[] fileContents, String contentType) at Microsoft.AspNetCore.Mvc.ControllerBase.File(Byte[] fileContents, String contentType, String fileDownloadName)

I can't figure out what is wrong here. Please advice.

When you add headers to the response, ASP.NET Core will validate known headers to make sure that they contain valid values. In your case, you are attempting to set the content type to "File Content." here:

repositoryMock
    .Setup(x => x.GetFile(It.IsAny<string>(), null))
    .ReturnsAsync(new FileContent("test.txt", "File Content.", Encoding.UTF8.GetBytes("File Content.")));
//                                            ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

But File Content. is not a valid MIME type , so the validation of that value fails.

Instead, you should use an actual MIME type, eg text/plain since you also have plain text contents in your test:

repositoryMock
    .Setup(x => x.GetFile(It.IsAny<string>(), null))
    .ReturnsAsync(new FileContent("test.txt", "text/plain", Encoding.UTF8.GetBytes("File Content.")));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM