باستخدام request.files.count مع TestControllerBuilder من MVCContrib؟
-
05-07-2019 - |
سؤال
لديّ إجراء وحدة تحكم في ASP.NET MVC الذي يتولى الملفات التي تم تحميلها. ومع ذلك ، يبدو أنه لا توجد طريقة للاتصال Request.Files.Count
أثناء استخدام MVCContrib's TestControllerBuilder
.
أعلم أنه يمكنني العمل حول هذا من خلال تجريده Request.Files
. أسئلتي هي:
- هل هو في الواقع أنه لا توجد طريقة مباشرة للاتصال
Request.Files.Count
عند استخدامTestControllerBuilder
؟ أم أفعل شيئًا خاطئًا؟ - هل هناك طريقة لاستدعاء الدعوة إلى
Request.Files.Count
أثناء استخدامTestControllerBuilder
باستخدام وحيد القرن الاستهزاء؟ - هل تعتقد أنني يجب أن أقدم طلبًا أو تصحيحًا للتعامل معه
Request.Files.Count
إلى MVCContrib؟
رمز المثال:
أريد أن أتأكد من وجود ملف واحد على الأقل في 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();
}
}
أنا أستخدم TestControllerBuilder
من MVCContrib لإنشاء اختبار مزدوج لاختبارات وحدة التحكم الخاصة بي. ومع ذلك ، الدعوة إلى Request.Files.Count
يبدو دائمًا أن يرمي استثناءً. على سبيل المثال تشغيل اختبار NUNIT التالي رمي أ NotImplementedException
أثناء الدعوة إلى 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
ولكن دون جدوى (أنا أستخدم Mocks وحيد القرن). لا شيء من العمل أدناه (حتى لو تغيرت controller
و/أو controllerBuilder
إلى كعب):
controllerBuilder.Stub(cb => cb.HttpContext.Request.Files.Count).Return(1);
controller.Stub(c => c.Request.Files.Count).Return(1);
شكرًا
المحلول
أنا قدمت رقعة على github إلى mantainers mvccontrib ، ولكن التغييرات بسيطة للغاية ، والمشكلة هي أن httpfilecollectionbase لا تنفذ العد () هذه الأساليب [int index] لذلك يجب تجاوزها بواسطة crinablehttpfilecollection في mvccontrib.
ألصق الكود هنا من أجل الاكتمال ، يجب إضافته إلى فئة WritableHttpFileCollection:
public override HttpPostedFileBase this[int index]
{
get { return files[AllKeys[index]]; }
}
public override int Count
{
get { return files.Count; }
}
نصائح أخرى
لقد استخدمت هذا النهج لحل المشكلة.
إعداد الاختبار: سلسلة filename = "test 1.pdf" ؛ Filestream Stream = file.openRead ("log4net.config") ؛ Mockrepository Mock = جديد 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...
}
}