Testen eines Web-API-Methode, die verwendet HttpContext.Aktuelle.Anfrage.Dateien?

Ich bin versucht zu schreiben, einen test für eine Web-API-Methode, die verwendet HttpContext.Current.Request.Files und nach eingehendem suchen und Experimentieren kann ich nicht herausfinden, wie zum Hohn für ihn. Getesteten Methode sieht wie folgt aus:

[HttpPost]
public HttpResponseMessage Post()
{
    var requestFiles = HttpContext.Current.Request.Files;
    var file = requestFiles.Get(0);
    //do some other stuff...
}

Ich weiß, dass es andere Fragen ähnlich wie diese, aber Sie tun es nicht auf diese bestimmte situation.

Wenn ich versuche zu verspotten, den Zusammenhang hatte ich Probleme mit der Http* Objekt-Hierarchie. Sagen, dass ich verschiedene mock-Objekte (mit Moq) wie folgt:

var mockFiles = new Mock<HttpFileCollectionBase>();
mockFiles.Setup(s => s.Count).Returns(1);
var mockFile = new Mock<HttpPostedFileBase>();
mockFile.Setup(s => s.InputStream).Returns(new MemoryStream());
mockFiles.Setup(s => s.Get(It.IsAny<int>())).Returns(mockFile.Object);
var mockRequest = new Mock<HttpRequestBase>();
mockRequest.Setup(s => s.Files).Returns(mockFiles.Object);
var mockContext = new Mock<HttpContextBase>();
mockContext.Setup(s => s.Request).Returns(mockRequest.Object);

Versucht, weisen Sie dem aktuellen Kontext...

HttpContext.Current = mockContext.Object;

...führt zu einem compiler-Fehler/redline, weil es Cannot convert source type 'System.Web.HttpContextBase' to target type 'System.Web.HttpContext'.

Ich habe auch versucht, bohren in verschiedenen Kontext-Objekte, die mit der gebauten controller-Objekt, aber nicht finden können, eine, ein) ist das Rückgabe-Objekt ein HttpContext.Current Aufruf der controller-Methode Körper und b) haben Sie Zugriff auf standard - HttpRequest Eigenschaften, wie Files.

var requestMsg = controller.Request;   //returns HttpRequestMessage
var context = controller.ControllerContext;  //returns HttpControllerContext
var requestContext = controller.RequestContext;   //read-only returns HttpRequestContext

Es ist auch wichtig zu beachten, dass die ich nicht ändern kann, den controller, den ich Teste, so kann ich nicht ändern Sie den Konstruktor zu ermöglichen, den Kontext injiziert werden.

Gibt es eine Möglichkeit, zu verspotten HttpContext.Current.Request.Files für unit-testing in Web-API?

Update

Obwohl, ich bin mir nicht sicher, ob dies akzeptiert wird von der Mannschaft, ich bin das Experimentieren mit dem ändern der Post-Methode zu verwenden Request.Content, wie vorgeschlagen, durch Martin Liversage. Derzeit sieht ungefähr so aus:

public async Task<HttpResponseMessage> Post()
{
    var uploadFileStream = new MultipartFormDataStreamProvider(@"C:\temp");
    await Request.Content.ReadAsMultipartAsync(uploadFileStream);
    //do the stuff to get the file
    return ActionContext.Request.CreateResponse(HttpStatusCode.OK, "it worked!");
}

Mein test sieht wie folgt aus:

var byteContent = new byte[]{};
var content = new MultipartContent { new ByteArrayContent(byteContent) };
content.Headers.Add("Content-Disposition", "form-data");
var controllerContext = new HttpControllerContext 
{
    Request = new HttpRequestMessage
        {
            Content = new MultipartContent { new ByteArrayContent(byteContent) }
        }
};

Nun ich bin immer ein Fehler auf ReadAsMultipartAsync:

System.IO.IOException: Error writing MIME multipart body part to output stream. ---> System.InvalidOperationException: The stream provider of type 'MultipartFormDataStreamProvider' threw an exception. ---> System.InvalidOperationException: Did not find required 'Content-Disposition' header field in MIME multipart body part.

  • Als beiseite, wenn Sie können nicht wirklich ändern, Ihren code zu löschen, die direkte Kopplung auf die HttpContext.Current Abhängigkeit, es ist eine langatmige Art zu tun diese per reflection
InformationsquelleAutor AJ. | 2015-07-02
Schreibe einen Kommentar