2011-07-12 56 views
2

如何測試控制器的下列行動:單元測試的操作使用reCAPTCHA

public ActionResult Edit(User usr) 
    { 
     if (!Microsoft.Web.Helpers.ReCaptcha.Validate(ConfigurationManager.AppSettings["reCaptchaPrivate"].ToString())) 
     { 
      ModelState.AddModelError("reCaptcha", PPRR.App_LocalResources.Global.ErrorFillReCaptcha); 
      return PartialView("Wrong", usr); 
     } 
     if (ModelState.IsValid) 
     {code..... }} 

回答

7

我會通過抽象的驗證碼驗證碼開始:

public interface ICaptchaValidator 
{ 
    bool Validate(); 
} 

,然後讓我的控制器的樣子像這樣:

public class FooController: Controller 
{ 
    private readonly ICaptchaValidator _validator; 
    public FooController(ICaptchaValidator validator) 
    { 
     _validator = validator; 
    } 

    public ActionResult Edit(User usr) 
    { 
     if (!_validator.Validate()) 
     { 
      ModelState.AddModelError("reCaptcha", PPRR.App_LocalResources.Global.ErrorFillReCaptcha); 
      return PartialView("Wrong", usr); 
     } 

     ... 
    } 
} 

現在你有削弱你的控制器和次路之間的耦合驗證碼驗證。這是一件好事,因爲它讓你的控制器的操作更容易進行單元測試。我們成功地使我們的控制器獨立於實施驗證的實際方式。

現在,只需選擇一個模擬框架,如Rhino Mocks,Moq,NSubstitute,然後在您的單元測試中爲此控制器注入一個殘缺的驗證器,以便您可以定義它的行爲。

我個人建議你MvcContrib.TestHelper(基於Rhino Mocks)來測試你的ASP.NET MVC應用程序。它有許多內置的好東西來模擬HttpContext並使單元測試變得容易。

這裏是驗證失敗的情況下如何進行測試的例子:

[TestMethod] 
public void FooController_Edit_Action_Should_Return_The_Wrong_Partial_If_Captcha_Validation_Fails() 
{ 
    // arrange 
    var validatorStub = MockRepository.GenerateStub<ICaptchaValidator>(); 
    var sut = new HomeController(validatorStub); 
    var user = new User(); 
    validatorStub.Stub(x => x.Validate()).Return(false); 

    // act 
    var actual = sut.Edit(user); 

    // assert 
    actual 
     .AssertPartialViewRendered() 
     .ForView("Wrong") 
     .WithViewData<User>() 
     .Equals(user); 
    Assert.IsFalse(sut.ModelState.IsValid); 
} 
2

作爲替代Darin的答案,我以前用過該處理的驗證碼,並增加了錯誤的ModelState定製ActionFilter 。它工作得很好,意味着驗證碼不是動作方法本身的一部分。