0

J'essaye d'écrire quelques tests unitaires pour mon ApiController et j'ai rencontré quelques problèmes.Comment moquer Request.form dans Web api

Voici mon TestMethod

 [TestMethod] 
     public void CustomerController_AddUnitTest() 
     { 


      var custid = Guid.NewGuid(); 
      var customers = new Customer() { CustomerName = "Enterprise", CustomerId = custid }; 
      var rmContext = MockRepository.GenerateMock<HttpContextBase>(); 
      var rmRequest = MockRepository.GenerateMock<HttpRequestBase>(); 
      rmContext.Stub(x => x.Request).Return(rmRequest); 
      var FormData = new NameValueCollection { { "FirstName", "Jonathan" }, { "LastName", "Danylko" } }; 
      rmRequest.Stub(r => r.Form).Return(FormData); 
      rmContext.Stub(p => p.Request).Return(rmRequest); 
      var forms = rmContext.Request.Form; 

> // here i am able to get forms value but i couldn't pass these value 
> to main controller 

      var mockRepository = MockRepository.GenerateMock<ICustomerService>(); 
      mockRepository.Stub(x => x.Add(new Customer())).IgnoreArguments().Return(1); 
      _customerController = new CustomerController(mockRepository); 
      var result = _customerController.CustomerAdd(); 
      Assert.IsNotNull(result); 
     } 

Ceci est mon code du contrôleur ressemble

public int CustomerAdd() 
    { 
     var localhost = HttpContext.Current.Request.Url.Authority; 
     var formData = HttpContext.Current.Request.Form["FormData"]; 
     JavaScriptSerializer json_serializer = new JavaScriptSerializer(); 
     var customer = json_serializer.Deserialize<Customer>(formData); 
     if (HttpContext.Current.Request.Files.Count > 0) 
     { 
      HttpPostedFile file = HttpContext.Current.Request.Files[0]; 
      string fileName = customer.CustomerName.Trim() + "_" + file.FileName; 
      var filePath = HttpContext.Current.Server.MapPath(Constants.FileUploadImagePath + fileName); 
      file.SaveAs(filePath); 
      customer.Logo = fileName; 
     } 
     return _iCustomerService.Add(customer); 
    } 

Je veux transmettre des données simulées pour var formData = HttpContext.Current.Request.Form["FormData"];

Quelqu'un peut-il avoir une idée pour résoudre ce problèmes ?? .. J'ai littéralement marre de cette tâche.

+0

La méthode testée est mal conçue et est étroitement couplée à des dépendances statiques qui la rendent difficile à tester. Essayez d'éviter de coupler étroitement votre code à 'HttpContext'. – Nkosi

+0

oui je le savais. Mais je ne sais pas comment se moquer de cette ligne de code –

+0

var formData = HttpContext.Current.Request.Form ["FormData"]; –

Répondre

0

Tirez la ligne dans une méthode séparée (virtuelle), puis dans vos tests, utilisez un simulacre partiel de votre contrôleur où vous avez stubbed la nouvelle méthode pour retourner vos données fictives. (Ceci est appelé un "test de couture" FYI).

Quelque chose comme ceci:

public int CustomerAdd() 
{ 
    var localhost = HttpContext.Current.Request.Url.Authority; 
    var formData = GetFormData()["FormData"]; 
    JavaScriptSerializer json_serializer = new JavaScriptSerializer(); 
    var customer = json_serializer.Deserialize<Customer>(formData); 
    if (HttpContext.Current.Request.Files.Count > 0) 
    { 
     HttpPostedFile file = HttpContext.Current.Request.Files[0]; 
     string fileName = customer.CustomerName.Trim() + "_" + file.FileName; 
     var filePath = HttpContext.Current.Server.MapPath(Constants.FileUploadImagePath + fileName); 
     file.SaveAs(filePath); 
     customer.Logo = fileName; 
    } 
    return _iCustomerService.Add(customer); 
} 

public virtual NameValueCollection GetFormDatat() 
{ 
    return HttpContext.Current.Request.Form; 
} 

Ensuite, utilisez dans votre test:

_customerController = MockRepository.GeneratePartialMock<CustomerContoller>(); 
_customerController.Stub(c => c.GetFormData()).Return(yourFakeFormData); 

Sinon, vous pouvez faire la même chose, mais pour des usages de l'objet de contexte.

+0

En règle générale, vous ne voulez jamais que votre code de production prenne directement une référence à vos types de frameworks fictifs. Dans la publication d'origine, vous montrez la classe du contrôleur en prenant le référentiel simulé comme paramètre constructeur - cela ne devrait jamais arriver. Le cadre factice est conçu pour se moquer des types que vous utilisez réellement afin que votre production n'ait pas besoin de connaître votre code de test. –