2009-02-09 12 views
5

Je suis en train d'écrire des tests unitaires pour mes contrôleurs dans RC1. Voici la signature publique du contrôleur je teste:Exigences de simulation pour TryUpdateModel dans ASP.Net RC1

 [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult AcceptColleague() 
    { 

La mise en œuvre à l'intérieur du AcceptColleague utilise la méthode TryUpdateModel (collègue) de peuplant l'objet collègue des champs de formulaire. Cependant, je cours dans une erreur "Référence d'objet non définie à une instance d'un objet" sur la ligne TryUpdateModel en essayant de tester la méthode unitaire.

Voici mon code de test unitaire:

  // definition 
     HomeController controller = new HomeController(); 
     IColleagueRepository fakeColleagueRepo = MockRepository.GenerateMock<IColleagueRepository>(); 
     Colleague requestedColleauge = new Colleague(); 
     EmployeeInfo currentUser = new EmployeeInfo();    
     HttpContextBase fakeHttpContext = MockRepository.GenerateMock<HttpContextBase>(); 
     HttpRequestBase fakeHttpRequest = MockRepository.GenerateMock<HttpRequestBase>(); 
     ControllerContext fakeContext = MockRepository.GenerateMock<ControllerContext>(fakeHttpContext, new RouteData(), controller); 
     NameValueCollection fakeForm = new NameValueCollection(); 

     // expectations 
     fakeColleagueRepo.Expect(c => c.Read(1234)).Return(requestedColleauge); 
     fakeColleagueRepo.Expect(c => c.Update(requestedColleauge)); 
     fakeColleagueRepo.Expect(c => c.Add(new Colleague())).IgnoreArguments().Constraints(Is.NotNull()); 
     fakeContext.Expect(cx => cx.HttpContext).Return(fakeHttpContext); 
     fakeHttpContext.Expect(hcx => hcx.Request).Return(fakeHttpRequest); 
     fakeHttpRequest.Expect(hr => hr.Form).Return(fakeForm); 

     // setup 
     controller.ColleagueRepository = fakeColleagueRepo; 
     controller.ControllerContext = fakeContext; 
     requestedColleauge.TargetEmployeeInfoId = 123456; 
     requestedColleauge.GeneratedEmployeeInfoId = 654321; 
     currentUser.EmployeeInfoId = 123456; 
     fakeForm.Add("ColleagueId", "22222"); 

     // action 
     RedirectToRouteResult result = controller.AcceptColleague() as RedirectToRouteResult; 

     // validation 
     Assert.IsNotNull(result, "AcceptColleague() did not return RedirectToRouteResult"); 

Suis-je manque quelque chose sur le moqueur ou devrais-je utiliser une autre signature publique comme AcceptColleague (collègue collègue) et ensuite tester la propriété ModelState.IsValid?

Si tel est le cas, comment ne vois-je pas comment masquer la propriété ModelState en lecture seule du contrôleur?

Répondre

13

TryUpdateModel et ModelState exigent tous les deux zéro mocks dans RC 1. La seule chose que vous devez fournir est un ValueProvider. Pour cela, vous pouvez utiliser FormCollection.ToValueProvider().

Vous aurez toujours besoin de vous moquer de votre référentiel, mais il n'y a rien que vous ayez besoin de simuler dans le cadre de cette fonctionnalité. Essayez ceci:

FormCollection fakeForm = new FormCollection(); 
    fakeForm.Add("ColleagueId", "22222"); 
    controller.ValueProvider = fakeForm.ToValueProvider(); 

    // action 

Remarque: Pas besoin de HttpContext, à moins que votre code ne l'exige.

+1

Craig, merci beaucoup. Je suppose que j'ai manqué cela dans la documentation flottante là-bas. Je travaille comme un charme maintenant. Merci encore, Cole –

+3

en fait, vous devez fournir un contexte, si vous ne vous obtenez ArgumentNullException, valeur ne peut pas être le nom null.Parameter: ControllerContext –

+0

Mvc 5.2.3 a l'exception Null Omar décrit ci-dessus. controller.ControllerContext = nouveau ControllerContext(); Permet à l'unité de test de progresser pour moi. – Anthony