Utilisation de Request.Files.Count avec TestControllerBuilder de MvcContrib?
-
05-07-2019 - |
Question
J'ai une action de contrôleur dans ASP.NET MVC qui gère les fichiers téléchargés. Cependant, il semble qu'il n'y ait aucun moyen d'appeler Request.Files.Count
lors de l'utilisation du TestControllerBuilder
de MvcContrib.
Je sais que je peux contourner ce problème en résumant Request.Files
. Mes questions sont:
- Est-il effectivement vrai qu'il n'existe aucun moyen direct d'appeler
Request.Files.Count
lors de l'utilisation deTestControllerBuilder
? Ou est-ce que je fais quelque chose de mal? - Y a-t-il moyen d'arrêter l'appel à
Request.Files.Count
en utilisantTestControllerBuilder
à l'aide de Rhino Mocks? - Pensez-vous que je devrais soumettre une demande ou un correctif pour gérer
Request.Files.Count
à MvcContrib?
Exemple de code:
Je veux m'assurer qu'il y a au moins un fichier dans la collection Request.Files
afin d'avoir le conditionnel suivant dans mon action:
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();
}
}
J'utilise TestControllerBuilder
de MvcContrib pour créer le double de test pour mes tests de contrôleur. Cependant, l'appel à Request.Files.Count
semble toujours générer une exception. Par exemple, l'exécution du test NUnit suivant génère une NotImplementedException
lors de l'appel de controller.Upload ()
lors de l'appel de 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);
}
J'ai également tenté d'arrêter l'appel à Request.Files.Count
en vain (j'utilise Rhino Mocks). Aucune des solutions ci-dessous ne fonctionne (même si je modifie controller
et / ou controllerBuilder
en un stub):
controllerBuilder.Stub(cb => cb.HttpContext.Request.Files.Count).Return(1);
controller.Stub(c => c.Request.Files.Count).Return(1);
Merci
La solution
Je a soumis un correctif sur Github à Mithconterrer. simple à faire, le problème est que HttpFileCollectionBase n’implémente pas les méthodes Count () et this [int index], elles doivent donc être remplacées par la WriteableHttpFileCollection de MvcContrib.
Je colle le code ici pour compléter, à ajouter à la classe WriteableHttpFileCollection:
public override HttpPostedFileBase this[int index]
{
get { return files[AllKeys[index]]; }
}
public override int Count
{
get { return files.Count; }
}
Autres conseils
J'ai utilisé cette approche pour résoudre le problème.
Configurez le test: 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);
}
en utilisant la maquette:
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...
}
}