¿Usando Request.Files.Count con TestControllerBuilder de MvcContrib?
-
05-07-2019 - |
Pregunta
Tengo una acción de controlador en ASP.NET MVC que maneja los archivos cargados. Sin embargo, parece que no hay manera de llamar a Request.Files.Count
mientras se usa TestControllerBuilder
de MvcContrib.
Sé que puedo solucionar esto al abstraer Request.Files
. Mis preguntas son:
- ¿Es cierto que no hay una forma directa de llamar a
Request.Files.Count
cuando se usaTestControllerBuilder
? ¿O estoy haciendo algo mal? - ¿Hay una manera de anular la llamada a
Request.Files.Count
mientras usaTestControllerBuilder
usando Rhino Mocks? - ¿Crees que debería enviar una solicitud o un parche para manejar
Request.Files.Count
a MvcContrib?
Código de ejemplo:
Quiero asegurarme de que haya al menos un archivo en la colección Request.Files
, por lo que tengo el siguiente condicional en mi acción:
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();
}
}
Estoy utilizando el TestControllerBuilder
de MvcContrib para crear el doble de prueba para mis pruebas de controlador. Sin embargo, la llamada a Request.Files.Count
siempre parece ser una excepción. Por ejemplo, la ejecución de la siguiente prueba NUnit lanza una NotImplementedException
durante la llamada a controller.Upload ()
en la llamada a 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);
}
También he intentado anular la llamada a Request.Files.Count
sin éxito (estoy usando Rhino Mocks). Ninguno de los siguientes trabajos (incluso si cambio controller
y / o controllerBuilder
a un código auxiliar):
controllerBuilder.Stub(cb => cb.HttpContext.Request.Files.Count).Return(1);
controller.Stub(c => c.Request.Files.Count).Return(1);
Gracias
Solución
I envió un parche en Github a Mvc para que nos guiemos en los recargos de los vajeros. fácil de hacer, el problema es que HttpFileCollectionBase no está implementando los métodos Count () y este [índice int], por lo que WritableHttpFileCollection en MvcContrib debe sobrescribirlos.
Pegue el código aquí para completar, que debe agregarse a la clase WriteableHttpFileCollection:
public override HttpPostedFileBase this[int index]
{
get { return files[AllKeys[index]]; }
}
public override int Count
{
get { return files.Count; }
}
Otros consejos
He utilizado este enfoque para resolver el problema.
Configura la prueba: 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);
}
utilizando el simulacro:
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...
}
}