asp.net-mvc – ASP .Net MVC 3:单元测试控制器动作
发布时间:2020-12-15 22:25:26 所属栏目:asp.Net 来源:网络整理
导读:我是单元测试和模拟概念的新手.我想弄清楚如何为下面的基本开箱即用用户注册代码编写一个好的测试用例: [HttpPost]public ActionResult Register(RegisterModel model){ if (ModelState.IsValid) { // Attempt to register the user MembershipCreateStatus
我是单元测试和模拟概念的新手.我想弄清楚如何为下面的基本开箱即用用户注册代码编写一个好的测试用例:
[HttpPost] public ActionResult Register(RegisterModel model) { if (ModelState.IsValid) { // Attempt to register the user MembershipCreateStatus createStatus; Membership.CreateUser(model.UserName,model.Password,model.Email,null,true,out createStatus); if (createStatus == MembershipCreateStatus.Success) { FormsAuthentication.SetAuthCookie(model.UserName,false /* createPersistentCookie */); return RedirectToAction("Index","Home"); } else { ModelState.AddModelError("",ErrorCodeToString(createStatus)); } } // If we got this far,something failed,redisplay form return View(model); } 以下是我需要您的意见/帮助的一些具体要点: >我不一定要在ASP .Net成员资格数据库中创建新用户. 解决方法
你的代码有问题.您的操作取决于静态方法:Membership.CreateUser.正如您所知,静态方法是用于单元测试的PITA.
所以你可以通过引入一个抽象级别来削弱耦合: public interface IMyService { MembershipCreateStatus CreateUser(string username,string password,string email); } 然后有一些使用当前成员资格提供者的实现: public class MyService: IMyService { public MembershipCreateStatus CreateUser(string username,string email) { MembershipCreateStatus status; Membership.CreateUser(username,password,email,out status); return status; } } 最后是控制器: public class AccountController : Controller { private readonly IMyService _service; public AccountController(IMyService service) { _service = service; } [HttpPost] public ActionResult Register(RegisterModel model) { if (ModelState.IsValid) { // Attempt to register the user var status = _service.CreateUser(model.UserName,model.Email); if (status == MembershipCreateStatus.Success) { FormsAuthentication.SetAuthCookie(model.UserName,false /* createPersistentCookie */); return RedirectToAction("Index","Home"); } else { ModelState.AddModelError("",ErrorCodeToString(createStatus)); } } // If we got this far,redisplay form return View(model); } } 好了,既然我们已经削弱了耦合,我们可以使用模拟框架来模拟单元测试中的服务并使其变得微不足道. 例如,使用Rhino Mocks,您可以创建以下测试以涵盖2个故障情况: [TestMethod] public void Register_Action_Should_Redisplay_View_If_Model_Is_Invalid() { // arrange var sut = new AccountController(null); var model = new RegisterModel(); sut.ModelState.AddModelError("","invalid email"); // act var actual = sut.Register(model); // assert Assert.IsInstanceOfType(actual,typeof(ViewResult)); var viewResult = actual as ViewResult; Assert.AreEqual(model,viewResult.Model); } [TestMethod] public void Register_Action_Should_Redisplay_View_And_Add_Model_Error_If_Creation_Fails() { // arrange var service = MockRepository.GenerateStub<IMyService>(); service .Stub(x => x.CreateUser(null,null)) .IgnoreArguments() .Return(MembershipCreateStatus.InvalidEmail); var sut = new AccountController(service); var model = new RegisterModel(); // act var actual = sut.Register(model); // assert Assert.IsInstanceOfType(actual,viewResult.Model); Assert.IsFalse(sut.ModelState.IsValid); } 最后的测试是成功案例.我们仍然有一个问题.问题是以下行: FormsAuthentication.SetAuthCookie(model.UserName,false); 这是什么?这是一个静态方法调用.因此,我们采用与成员资格提供程序相同的方式来削弱控制器和表单身份验证系统的耦合. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- asp.net-mvc – 如何在mvc中保持视图不受授权逻辑的影响?
- asp.net中的页面卸载事件
- 如何在ASP.NET Web应用程序(而不是MVC)中使用Razor语法
- asp.net-identity – asp.net标识有什么用.GenerateUserTok
- asp.net-mvc – MVC6自托管wwwroot内容返回404,IIS Express
- asp-classic – 如何在经典的asp中读取文本文件
- asp.net – MVC 3中的SessionState属性是否正常工作?
- 在运行ASP.NET的Web场中,您使用什么进行分布式缓存?
- asp.net – 如何在MVC Razor中处理null子实体
- asp.net-mvc – 如何在WEB API 2中创建异步验证属性
推荐文章
站长推荐
热点阅读