Essai d'une API Web méthode qui utilise HttpContext.Actuel.Demande.Fichiers?
J'essaie d'écrire un test pour une Web API méthode qui utilise HttpContext.Current.Request.Files
et, après une recherche et d'expérimentation je ne peux pas comprendre comment, à se moquer. La méthode testée ressemble à ceci:
[HttpPost]
public HttpResponseMessage Post()
{
var requestFiles = HttpContext.Current.Request.Files;
var file = requestFiles.Get(0);
//do some other stuff...
}
Je me rends compte qu'il y a d'autres questions similaire à ce, mais ils ne traitent pas de cette situation spécifique.
Si je tente de simuler le contexte, je rencontre des problèmes avec le Http*
hiérarchie d'objets. Dire que j'ai mis en place divers objets fantaisie (à l'aide de Moq) comme ceci:
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);
Tentant de l'attribuer le contexte actuel...
HttpContext.Current = mockContext.Object;
...génère une erreur de compilation/redline, car il Cannot convert source type 'System.Web.HttpContextBase' to target type 'System.Web.HttpContext'
.
J'ai aussi essayé de forage dans divers contexte des objets qui viennent avec la construction de l'objet contrôleur, mais ne pouvez pas en trouver un qui a) est l'objet de retour d'un HttpContext.Current
appel à la méthode de contrôleur corps et b) permet d'accéder à la norme HttpRequest
propriétés, comme Files
.
var requestMsg = controller.Request; //returns HttpRequestMessage
var context = controller.ControllerContext; //returns HttpControllerContext
var requestContext = controller.RequestContext; //read-only returns HttpRequestContext
Il est également important de noter que je ne peux pas changer le contrôleur que je suis en essais à tous, donc je ne peux pas changer le constructeur pour permettre le contexte pour être injecté.
Est-il une manière de se moquer de HttpContext.Current.Request.Files
pour les tests unitaires dans l'API Web?
Mise à jour
Si je ne suis pas sûr que cela va être accepté par l'équipe, je suis expérimenter avec la modification de la méthode Post pour utiliser Request.Content
, comme suggéré par Martin Liversage. Actuellement, il ressemble à quelque chose comme ceci:
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!");
}
Mon test ressemble à ceci:
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) }
}
};
Maintenant j'ai une erreur sur 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.
HttpContext.Current
de dépendance, il est un de longue haleine façon de faire ce par le biais d'une réflexion
OriginalL'auteur AJ. | 2015-07-02
Vous devez vous connecter pour publier un commentaire.
API Web a été conçu pour appuyer les tests unitaires en vous permettant de vous moquer de diverses contexte des objets. Cependant, en utilisant
HttpContext.Current
vous utilisez "old-style"System.Web
code qui utilise laHttpContext
classe qui rend impossible l'unité de tester votre code.Pour permettre à votre code à l'unité testable, vous devez cesser d'utiliser
HttpContext.Current
. Dans L'envoi des Données du Formulaire HTML dans ASP.NET l'API Web: Téléchargement de Fichiers et de messages MIME en plusieurs parties vous pouvez voir comment télécharger des fichiers à l'aide de l'API Web. Ironiquement, ce code utilise aussiHttpContext.Current
pour obtenir l'accès à laMapPath
mais dans l'API Web vous devez utiliserHostingEnvironment.MapPath
qui fonctionne aussi à l'étranger IIS. Se moquer de la plus tard est également problématique, mais pour l'instant je suis en se concentrant sur votre question au sujet de se moquer de la demande.Pas à l'aide de
HttpContext.Current
permet à l'unité de tester votre contrôleur en lui assignant leControllerContext
propriété du contrôleur:J'ai mis à jour le code. Vous devez définir le
Content-Disposition
en-tête du contenu interne, pas sur la partie multi-contenu.J'essaie de faire ce travail, et de ne pas avoir beaucoup de chance - si vous avez le temps, vous pouvez prendre un coup d'oeil à cette s'il vous plaît? stackoverflow.com/questions/44073646/...
OriginalL'auteur Martin Liversage
Accepté la réponse est parfait pour les OP de la question. Je voulais ajouter ma solution ici, qui dérive de Martin, en tant que ceci est la page j'ai été dirigé vers une simple recherche sur la façon de se Moquer de l'objet de Demande de Web API afin que je puisse ajouter des en-têtes dans mon Contrôleur est à la recherche pour. J'ai eu un moment difficile de trouver la réponse est simple:
Et vous y êtes; une manière très simple de créer contrôleur de contexte avec lequel vous pouvez "se Moquer de" l'objet de Demande et d'assurer un approvisionnement correct en-têtes de votre méthode de Contrôleur.
OriginalL'auteur iGanja
J'ai raillé juste posté fichier. Je crois que tous les fichiers peuvent également être moqué de cette façon.
OriginalL'auteur Abhishek