我會通過抽象的驗證碼驗證碼開始:
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);
}