سؤال

لديّ إجراء وحدة تحكم في ASP.NET MVC الذي يتولى الملفات التي تم تحميلها. ومع ذلك ، يبدو أنه لا توجد طريقة للاتصال Request.Files.Count أثناء استخدام MVCContrib's TestControllerBuilder.

أعلم أنه يمكنني العمل حول هذا من خلال تجريده Request.Files. أسئلتي هي:

  1. هل هو في الواقع أنه لا توجد طريقة مباشرة للاتصال Request.Files.Count عند استخدام TestControllerBuilder؟ أم أفعل شيئًا خاطئًا؟
  2. هل هناك طريقة لاستدعاء الدعوة إلى Request.Files.Count أثناء استخدام TestControllerBuilder باستخدام وحيد القرن الاستهزاء؟
  3. هل تعتقد أنني يجب أن أقدم طلبًا أو تصحيحًا للتعامل معه 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...
            }
        }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top