单元测试ASP.NETMVC5应用)publicclassApplicationUser:IdentityUser{publicDateTimeBirthDate{get;set;}}现在我想创建一个单元测试来验证我的AccountController是否正确保存了BirthDate。我创建了一个内存中的用户存储,名为TestUserStore[TestMethod]publicvoidRegister(){//ArrangevaruserManager=newUserManager(newTestUserStore());varcontroller=newAccountController(userManager);//这将使用Moqcontroller.SetFakeControllerContext()设置一个假的HttpContext;//Actvarresult=controller.Register(newRegisterViewModel{BirthDate=TestBirthDate,UserName=TestUser,Password=TestUserPassword,ConfirmPassword=TestUserPassword}).Result;//断言Assert.IsNotNull(result);varaddedUser=userManager.FindByName(TestUser);断言.IsNotNull(addedUser);Assert.AreEqual(TestBirthDate,addedUser.BirthDate);controller.Register方法是由MVC5生成的样板代码,但出于参考目的,我将其包含在此处。当我运行这个测试时,我得到一个异常测试方法MVCLabMigration.Tests.Controllers.AccountControllerTest.Register抛出异常:System.AggregateException:发生一个或多个错误。--->System.NullReferenceException:对象引用未设置为对象的实例。在System.Web.HttpContextBaseExtensions.GetOwinEnvironment(HttpContextBase上下文)在System.Web.HttpContextBaseExtensions.GetOwinContext(HttpContextBase上下文)在MVCLabMigration.Controllers.AccountController.get_AuthenticationManager()在Account.Controller.cs:在第33行AccountController.d__40.MoveNext()在AccountController.cs中:第336行在以前的版本中,ASP.NETMVC团队非常努力地使代码可测试。从表面上看,现在测试AccountController并不容易。我有一些选择。我可以修改样板代码,这样它就不会调用扩展方法并在那个级别处理它设置OWin管道进行测试避免编写需要AuthN/AuthZ基础结构的测试代码(不是一个合理的选择)我不确定哪条路更好。谁能解决这个问题。我的问题归结为最佳策略。注意:是的,我知道我不需要测试不是我写的代码。//添加这个私有变量privateIAuthenticationManager_authnManager;//将其从私有修改为公共并添加设置器返回_authnManager;}设置{_authnManager=值;}}步骤2:修改单元测试为Microsoft.OWin.IAuthenticationManager接口添加模拟[TestMethod]publicvoidRegister(){//ArrangevaruserManager=newUserManager(newTestUserStore());varcontroller=newAccountController(userManager);controller.SetFakeControllerContext();//修改测试以设置模拟IAuthenticationManagervarmockAuthenticationManager=newMock();mockAuthenticationManager.Setup(am=>am.SignOut());mockAuthenticationManager.Setup(am=>am.SignIn());//将它添加到控制器-这就是为什么你必须制作一个公共设置器controller.AuthenticationManager=mockAuthenticationManager.Object;//ApublicLoginHandler(HttpContextBasehttpContext,IAuthenticationManagerauthManager){_httpContext=httpContext;_authManager=authManager;我正在使用Unity来注册我的依赖项:container.RegisterType(newInjectionFactory(c=>c.Resolve().GetOwinContext()));container.RegisterType(newInjectionFactory(c=>c.Resolve().Authentication));容器.RegisterType();//Furtherregistrationshere...}但是,我想测试我的Unity注册,如果不伪造(a)HttpContext.Current(足够难)和(b)GetOwinContext()-正如你所做的那样,这已被证明是棘手的发现,不能直接做。我从PhilHaack的HttpSimulatorforms和HttpContext的一些操作中找到了一个解决方案来创建一个基本的Owin环境。到目前为止,我发现设置一个虚拟Owin变量足以使GetOwinContext()工作,但是YMMV。如需转载请注明出处:
