使用来自MvcContrib的TestControllerBuilder的Request.Files.Count?

时间:2009-07-29 21:59:57

标签: asp.net-mvc unit-testing mvccontrib

我在ASP.NET MVC中有一个处理上传文件的控制器操作。但是,在使用MvcContrib的Request.Files.Count时似乎无法调用TestControllerBuilder

我知道我可以通过摘要Request.Files来解决这个问题。我的问题是:

  1. 使用Request.Files.Count时是否确实无法直接调用TestControllerBuilder?或者我做错了什么?
  2. 使用Request.Files.Count使用Rhino Mocks时,有没有办法将调用存根到TestControllerBuilder
  3. 您认为我应该向MvcContrib提交处理Request.Files.Count的请求或补丁吗?
  4. 示例代码:

    我想确保Request.Files集合中至少有一个文件,所以我的行动中有以下条件:

    public class MyController : Controller {
        public ActionResult Upload() {
            if (Request.Files == null || Request.Files.Count == 0)
                ViewData.ModelState.AddModelError("File", "Please upload a file");
            // do stuff
            return View();
        }
    }
    

    我正在使用MvcContrib中的TestControllerBuilder来为我的控制器测试创建测试双。但是,对Request.Files.Count的调用似乎总是抛出异常。例如,在致电NotImplementedException时,运行以下NUnit测试会在致电controller.Upload()期间抛出Request.Files.Count

    [Test]
    public void Upload_should_return_default_view_given_one_file() {
        MyController controller = new MyController();
        TestControllerBuilder controllerBuilder = new TestControllerBuilder();
        controllerBuilder.InitializeController(controller);
        controllerBuilder.Files["file"] = 
            MockRepository.GenerateStub<HttpPostedFileBase>();
    
        var result = controller.Upload() as ViewResult;
    
        Assert.That(result.ViewData.ModelState.IsValid, Is.True);
        result.AssertViewRendered().ForView(string.Empty);
    }
    

    我还试图将对Request.Files.Count的调用无效(我正在使用Rhino Mocks)。以下都不起作用(即使我将controller和/或controllerBuilder更改为存根:

    controllerBuilder.Stub(cb => cb.HttpContext.Request.Files.Count).Return(1);
    controller.Stub(c => c.Request.Files.Count).Return(1);
    

    由于

2 个答案:

答案 0 :(得分:1)

我在Github上的submitted a patch到MvcContrib mantainers,但是变化非常简单,问题是HttpFileCollectionBase没有实现Count()和这个[int index]方法所以它们必须被WriteableHttpFileCollection覆盖在MvcContrib。

我在这里粘贴代码是为了完整性,必须添加到WriteableHttpFileCollection类:

public override HttpPostedFileBase this[int index]
{
    get { return files[AllKeys[index]]; }
}

public override int Count
{
    get { return files.Count; }
}

答案 1 :(得分:0)

我已经用这种方法来解决问题。

设置测试:             string fileName =“Test 1.pdf”;             FileStream stream = File.OpenRead(“log4net.config”);             MockRepository mock = new MockRepository();

        builder.Files[fileName] = mock.CreateMock<HttpPostedFileBase>();
        using (mock.Record())
        {
            Expect.Call(builder.Files[fileName].FileName)
                  .Return(fileName);
            Expect.Call(builder.Files[fileName].ContentType)
                  .Return(contentType);
            Expect.Call(builder.Files[fileName].ContentLength)
                  .Return(Convert.ToInt32(stream.Length.ToString()));
            Expect.Call(builder.Files[fileName].InputStream)
                  .Return(stream);
        }

使用模拟:

        foreach(string key in Request.Files.AllKeys)
        {
            int lenght = Request.Files[key].ContentLength;
            if (lenght > 0)
            {
                Document document = new Document();
                string fileName = Request.Files[key].FileName;
                byte[] content= new byte[Convert.ToInt32(lenght)];
                Request.Files[key].InputStream.Read(content, 0, content.Length);
                document.SetContent(content);
                document.MimeType = Request.Files[key].ContentType;
                // do whatever you want...
            }
        }