Verwenden Sie Request.files.count mit testControllerBuilder von mvccontrib?
-
05-07-2019 - |
Frage
Ich habe eine Controller -Aktion in ASP.NET MVC mit hochgeladenen Dateien. Es scheint jedoch, dass es keine Möglichkeit gibt, anzurufen Request.Files.Count
Während der Verwendung von mvccontribs TestControllerBuilder
.
Ich weiß Request.Files
. Meine Fragen sind:
- Ist es in der Tat der Fall, dass es keinen direkten Weg gibt, um anzurufen?
Request.Files.Count
Bei Verwendung derTestControllerBuilder
? Oder mache ich etwas falsch? - Gibt es eine Möglichkeit, den Anruf an zu stürzen?
Request.Files.Count
während dem BenutzenTestControllerBuilder
Verwenden von Rhino -Mocks? - Denken Sie, ich sollte eine Anfrage oder einen Patch zum Handling einreichen
Request.Files.Count
zu mvccontrib?
Beispielcode:
Ich möchte sicherstellen, dass es mindestens eine Datei in der gibt Request.Files
Sammlung, also habe ich die folgende Bedingung in meiner Aktion:
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();
}
}
Ich benutze das TestControllerBuilder
von MVCContrib zum Erstellen des Test -Double für meine Controller -Tests. Allerdings der Anruf zu Request.Files.Count
Scheint immer eine Ausnahme zu machen. Zum Beispiel wirft der folgende Nunit -Test a NotImplementedException
während des Anrufs an controller.Upload()
am Anruf an 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);
}
Ich habe auch versucht, den Anruf zum Stub zu bringen Request.Files.Count
ohne Erfolg (ich benutze Rhino Mocks). Keine der folgenden Arbeiten (auch wenn ich mich ändere controller
und/oder controllerBuilder
zu einem Stummel):
controllerBuilder.Stub(cb => cb.HttpContext.Request.Files.Count).Return(1);
controller.Stub(c => c.Request.Files.Count).Return(1);
Vielen Dank
Lösung
ich Ein Patch eingereicht Auf GitHub zu MVCContrib Mantainern, aber die Änderungen sind sehr einfach zu erzeugen, ist das Problem, dass httpfilecollectionBase keine count () und diese [int Index] -Methoden implementiert, sodass sie von der Schreibableerhttpfilecollection in mvccontrib überschrieben werden müssen.
Ich füge den Code hier für die Vollständigkeit ein, die zur Schreibableerhttpfilecollection -Klasse hinzugefügt werden muss:
public override HttpPostedFileBase this[int index]
{
get { return files[AllKeys[index]]; }
}
public override int Count
{
get { return files.Count; }
}
Andere Tipps
Ich habe diesen Ansatz verwendet, um das Problem zu lösen.
Richten Sie den Test ein: String Dateiname = "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);
}
Verwenden des Mocks:
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...
}
}