加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc-3 – 将Mocked HttpPostedFileBase作为MVC 3控制器

发布时间:2020-12-16 09:23:57 所属栏目:asp.Net 来源:网络整理
导读:我有一个Mock挑战 – 我正在使用MVC 3和nunit框架并试图模拟一个控制器有一个HttpPostedFileBase作为参数.控制器签名如下所示: public ActionResult UploadAttachment(AttachmentViewModel clientAttachment,HttpPostedFileBase file,string clientName) 我
我有一个Mock挑战 – 我正在使用MVC 3和nunit框架并试图模拟一个控制器有一个HttpPostedFileBase作为参数.控制器签名如下所示:

public ActionResult UploadAttachment(AttachmentViewModel clientAttachment,HttpPostedFileBase file,string clientName)

我为我的“文件”参数设置了一个模拟参考,但它抱怨它不会采用模拟对象.我猜我需要为这个场景设置一个ControllerContext,但我也没有任何运气.对于第一个测试,我只需要HttpPostedFileBase返回一个空文件(在空白文件引用进入的情况下).我还阅读了Scott Hanselman关于这个主题的优秀文章(computer Zen).对于我关注的MVC部分中的关键句似乎是“当你创建自己的ControllerContext时,你将在Web服务器外部运行时(例如在测试中)获得动态生成的HttpRequestBase的Mock.”这似乎是我遇到墙壁的地方.

我知道我需要这些元素:

controller.ControllerContext = new ControllerContext(mockContext.Object,new RouteData(),controller);
mockContext.SetupGet(c => c.Request).Returns(mockRequest.Object);
mockRequest.Setup(c => c.HttpMethod).Returns([not sure what to evoke here]);

我处于被困状态.感谢您提出正确方向的建议或推动.

解决方法

假设您使用实际视图模型(由控制器操作使用,而不是使用大量参数):

public class MyViewModel
{
    public HttpPostedFileBase File { get; set; }

    // those won't be used in my example but you get the point
    public string ClientName { get; set; }
    public AttachmentViewModel ClientAttachment { get; set; }
}

和一个控制器,其中包含您尝试进行单元测试的操作:

public class HomeController : Controller
{
    [HttpPost]
    public ActionResult UploadAttachment(MyViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        var file = Path.Combine(Server.MapPath("~/App_Data"),model.File.FileName);
        model.File.SaveAs(file);
        return RedirectToAction("succes");
    }
}

你现在有2个案例要涵盖:

>无效的modelstate =>返回一个视图
>有效的modelstate =>文件已保存,我们重定向.

让我们滚动:

[TestMethod]
public void UploadAttachment_Should_Return_View_If_ModelState_Is_Not_Valid()
{
    // arrange
    var sut = new HomeController();
    var model = new MyViewModel();
    sut.ModelState.AddModelError("file","please select a file");

    // act
    var actual = sut.UploadAttachment(model);

    // assert
    Assert.IsInstanceOfType(actual,typeof(ViewResult));
}

当然还有第二种情况:

[TestMethod]
public void UploadAttachment_Should_Save_File_If_Model_Is_Valid_And_Redirect()
{
    // arrange
    var sut = new HomeController();
    var file = new Mock<HttpPostedFileBase>();
    file.Setup(x => x.FileName).Returns("foo.txt");
    var model = new MyViewModel
    {
        File = file.Object
    };
    var server = new Mock<HttpServerUtilityBase>();
    server.Setup(x => x.MapPath("~/App_Data")).Returns(@"c:wwwrootApp_Data");
    var httpContext = new Mock<HttpContextBase>();
    httpContext.Setup(x => x.Server).Returns(server.Object);
    sut.ControllerContext = new ControllerContext(httpContext.Object,sut);

    // act
    var actual = sut.UploadAttachment(model);

    // assert
    Assert.IsInstanceOfType(actual,typeof(RedirectToRouteResult));
    file.Verify(x => x.SaveAs(@"c:wwwrootApp_Datafoo.txt"));
}

希望这会让你走上正轨.对不起,它使用MSTest而不是NUnit,但端口应该不仅仅是微不足道的(不应该超过30个工作秒).用[Test]替换[TestMethod],你不应该远离目标.是的,我打赌2¢这个Assert.IsInstanceOfType在NUnit中有一个等价物.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读