2009-11-10 2 views
1

UpdateModel을 사용하는 컨트롤러 작업을 단위 테스트하려고하지만 HttpContext를 올바르게 조롱하지 않았습니다. 다음 예외가 계속 발생합니다.ASP.Net MVC 용 UpdateModel을 어떻게 위조합니까?

System.InvalidOperationException : 이전 메서드 인 'HttpRequestBase.get_Form();' 던질 때 반환 값 또는 예외가 필요합니다.

HttpContext를 모의하려면 scott posted for Rhino mocks과 비슷한 것을 사용하고 있습니다.

나는 'HttpRequestBase.get_Form();'을 조롱 할 것이라고 생각했던 것에 대한 한 가지 방법을 추가했습니다. 내가 어떤 제대로 내 SetupRequestForm을 수정 대답, 단위 테스트를 받아, 또는를 게시합니다

[Authorize] 
[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(int id, FormCollection collection) 
{ 
    var campaign = Campaign.GetCampaign(id); 

    if (campaign == null) 
     return View("Error", ViewData["message"] = "Oops, could not find your requested campaign."); 
    if (!campaign.CanEdit(User.Identity.Name)) 
     return View("Error", ViewData["message"] = "You are not authorized to edit this campaign style."); 

    var style = campaign.GetStyle(); 
    //my problem child for tests. 
    UpdateModel(style); 

    if (!style.IsValid) 
    { 
     ModelState.AddModelErrors(style.GetRuleViolations()); 
     return View("Edit", style); 
    } 

    style.Save(User.Identity.Name); 
    return RedirectToAction("Index", "Campaign", new { id }); 
} 

: 시험

[Test] 
public void Edit_GivenFormsCollection_CanPersistStyleChanges() 
{ 
    //in memory db setup omitted ... 

    var nameValueCollection = new NameValueCollection(); 
    InitFormCollectionWithSomeChanges(nameValueCollection, style); 
    var httpContext = _mock.FakeHttpContext(); 
    _mock.SetFakeControllerContext(controller, httpContext); 
    httpContext.Request.SetupRequestForm(nameValueCollection); 

    controller.Edit(1, new FormCollection(nameValueCollection)); 

    var result = (ViewResult)controller.Edit(1); 

    Assert.IsNotNull(result.ViewData); 
    style = Style.GetStyle(1); 
    AsserThatModelCorrectlyPersisted(style); 

} 

컨트롤러 조치 : 여기

public static void SetupRequestForm(this HttpRequestBase request, NameValueCollection nameValueCollection) 
{ 
    if (nameValueCollection == null) 
     throw new ArgumentNullException("nameValueCollection"); 
    SetupResult.For(request.PathInfo).Return(string.Empty); 
    SetupResult.For(request.Form).Return(nameValueCollection); 
} 

는 단위 테스트입니다 동일한 목표를 달성하기 위해 MVCContrib 프로젝트에서 테스트 도우미를 사용하는 방법에 대한 예제.

+0

을 : 테스트는 지금처럼 읽을 수 있을까? –

+0

get에서보기로 전달되는 모델은 Strongly typed입니다. 나는 당신이 강하게 타자를 친 모형을 활동에 배치 할 수 있었다는 것을 몰랐다. – Aaron

+0

ViewData [ "message"]가 오류와 함께 사용되어 무언가가 잘못되었을 때 메시지를 보내는 일반적인 공유보기를 봅니다. – Aaron

답변

3

당신이 당신에게 전달한 FormCollection을 사용하고 있지 않습니다. 일반적으로 FormCollection에 전달하는 이유는 HttpConext에 대한 UpdateModel 종속성을 위반하여 테스트를 돕는 것입니다. 당신이 당신의 모의 HttpContext를 설정에 대한 잊을 수 있음을 완료하면

UpdateModel(style, collection.ToValueProvider()); 

:

당신이해야 할 모든

은에 UpdateModel 줄을 변경합니다. 예 : 방금 강력한 형식을 ViewData 개체를 사용하지 않으려는 확신이의 복잡성을 감안할 때,

[Test] 
public void Edit_GivenFormsCollection_CanPersistStyleChanges() 
{ 
    //Blah 

    var nameValueCollection = new NameValueCollection(); 
    InitFormCollectionWithSomeChanges(nameValueCollection, style); 
    //Removed stuff 

    controller.Edit(1, new FormCollection(nameValueCollection)); 

    //Blah 
} 

HTHs
찰스

+0

나는 여전히 HttpContext를 User.Identity 호출로 조롱해야하지만 돈은 당신이다. – Aaron

+0

사실 true ... 해당 User.Identity 호출에 관심을 기울이지 않았다 :-) – Charlino

관련 문제