单元测试带有伪HTTPContext的ASP.NET Web API控制器

Pyl*_*iev 25 c# asp.net unit-testing asp.net-mvc-4

我正在使用以下方法通过ASP.NET Web API控制器上传文件.

[System.Web.Http.HttpPost]
public HttpResponseMessage UploadFile()
{
    HttpResponseMessage response;

    try
    {
        int id = 0;
        int? qId = null;
        if (int.TryParse(HttpContext.Current.Request.Form["id"], out id))
        {
            qId = id;
        }

        var file = HttpContext.Current.Request.Files[0];

        int filePursuitId = bl.UploadFile(qId, file);
    }
    catch (Exception ex)
    {

    }

    return response;
}
Run Code Online (Sandbox Code Playgroud)

在我的单元测试中,我HTTPContext在调用操作之前手动创建了一个类UploadFile:

var request = new HttpRequest("", "http://localhost", "");
var context = new HttpContext(request, new HttpResponse(new StringWriter()));
HttpContext.Current = context;

response = controller.UploadFile();
Run Code Online (Sandbox Code Playgroud)

不幸的是,我无法为Form集合添加自定义值,因为它是只读的.我也无法改变Files收藏品.

有没有办法在单元测试期间添加自定义值Form以及添加所需数据(id和文件内容)的Files属性Request

Sun*_*nov 1

请改用一些模拟框架,例如Moq。使用您需要的任何数据创建模拟 HttpRequestBase 和模拟 HttpContextBase 并将它们设置在控制器上。

using Moq;
using NUnit.Framework;
using SharpTestsEx;

namespace StackOverflowExample.Moq
{
    public class MyController : Controller
    {
        public string UploadFile()
        {
            return Request.Form["id"];
        }
    }

    [TestFixture]
    public class WebApiTests
    {
        [Test]
        public void Should_return_form_data()
        {
            //arrange
            var formData = new NameValueCollection {{"id", "test"}};
            var request = new Mock<HttpRequestBase>();
            request.SetupGet(r => r.Form).Returns(formData);
            var context = new Mock<HttpContextBase>();
            context.SetupGet(c => c.Request).Returns(request.Object);

            var myController = new MyController();
            myController.ControllerContext = new ControllerContext(context.Object, new RouteData(), myController);

            //act
            var result = myController.UploadFile();

            //assert
            result.Should().Be.EqualTo(formData["id"]);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢你的回复。由于我们使用 web.api 控制器,我们需要使用 HttpControllerContext 而不是 ControllerContext。HttpControllerContext 不允许传入构造函数 HttpContextBase。 (22认同)
  • 只是想知道为什么当 Pylyp Lebediev 说是真的时,这会被投票...... (3认同)