使用来自MvcContrib的TestControllerBuilder的Request.Files.Count?
-
05-07-2019 - |
题
我在ASP.NET MVC中有一个处理上传文件的控制器操作。但是,在使用MvcContrib的 TestControllerBuilder
时,似乎无法调用 Request.Files.Count
。
我知道我可以通过抽象 Request.Files
来解决这个问题。我的问题是:
- 在使用
TestControllerBuilder
时,是否确实没有直接的方法来调用Request.Files.Count
?或者我做错了什么? - 使用
TestControllerBuilder
使用Rhino Mocks时,有没有办法将对Request.Files.Count
的调用存根? - 您认为我应该向MvcContrib提交处理
Request.Files.Count
的请求或补丁吗?
醇>
示例代码:
我想确保 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
的调用似乎总是抛出异常。例如,在调用 Request.Files.Count
时,在调用 controller.Upload()
期间运行以下NUnit测试会抛出 NotImplementedException
:
[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);
由于
解决方案
我在Github上向MvcContrib mantainers 提交了补丁,但变化非常大简单来说,问题是HttpFileCollectionBase没有实现Count()和this [int index]方法,所以它们必须被MvcContrib中的WriteableHttpFileCollection覆盖。
我在这里粘贴代码是为了完整性,必须添加到WriteableHttpFileCollection类:
public override HttpPostedFileBase this[int index]
{
get { return files[AllKeys[index]]; }
}
public override int Count
{
get { return files.Count; }
}
其他提示
我已经用这种方法来解决问题。
设置测试: string fileName =&quot; Test 1.pdf&quot ;; FileStream stream = File.OpenRead(&quot; log4net.config&quot;); 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...
}
}