我是ASP.Net MVC
和Identity
的新手。在ASP.Net MVC注册码上运行单元测试时出错使用ASP.Net身份
我有以下单元测试方法。
[TestMethod]
public void SignUp()
{
try
{
var dummyUser = new ApplicationUser() { UserName = "xyz", Email = "[email protected]" };
ViewModels.RegisterViewModel rvm = new ViewModels.RegisterViewModel { Name = "abc", Email = "[email protected]", Password = "123456" };
var store = new Mock<IUserStore<ApplicationUser>>();
store.As<IUserPasswordStore<ApplicationUser>>()
.Setup(x => x.FindByIdAsync(It.IsAny<string>()))
.ReturnsAsync(new ApplicationUser() { Id = "id" });
store.Setup(x => x.CreateAsync(dummyUser)).Returns(Task.FromResult(IdentityResult.Success));
store.As<IUserRoleStore<ApplicationUser>>().Setup(x => x.AddToRoleAsync(It.IsAny<ApplicationUser>(), It.IsAny<string>())).Returns(Task.FromResult(IdentityResult.Success));
store.As<IUserRoleStore<ApplicationUser>>().Setup(x => x.IsInRoleAsync(It.IsAny<ApplicationUser>(), It.IsAny<string>())).ReturnsAsync(true);
store.As<IRoleStore<IdentityRole>>().Setup(x => x.CreateAsync(new IdentityRole("I"))).Returns(Task.FromResult(IdentityResult.Success));
//var roleStore = new Mock<IRoleStore<IdentityRole>>();
//roleStore.As<IRoleStore<IdentityRole>>();
//roleStore.Setup(x => x.CreateAsync(new IdentityRole("I"))).Returns(Task.FromResult(IdentityResult.Success));
//var testRoleManager = new ApplicationRoleManager(roleStore.Object);
//to register usertokenprovider as it is needed to send confirmation email
var provider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("Sample");
var testUserManager = new ApplicationUserManager(store.Object);
testUserManager.UserTokenProvider =new DataProtectorTokenProvider<ApplicationUser>(provider.Create("ASP.NET Identity"));
// mocking IAuthenticationManager
var mockAuthenticationManager = new Mock<IAuthenticationManager>();
mockAuthenticationManager.Setup(am => am.SignOut());
mockAuthenticationManager.Setup(am => am.SignIn());
//mocking Context
var routes = new System.Web.Routing.RouteCollection();
ProChartSiteMVC.RouteConfig.RegisterRoutes(routes);
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost:1431/a", UriKind.Absolute));
request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection());
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
response.Setup(x => x.ApplyAppPathModifier("/post1")).Returns("http://localhost:1431/post1");
var context = new Mock<HttpContextBase>(MockBehavior.Strict);
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
var testSignInManager = new ApplicationSignInManager(testUserManager,mockAuthenticationManager.Object);
BussinessLayer bussinessLayer = new BussinessLayer(db);
AccountController controller = new AccountController(testUserManager,testSignInManager, bussinessLayer);
var UrlHelperMock = new Mock<UrlHelper>();
controller.Url = UrlHelperMock.Object;
controller.ControllerContext = new ControllerContext(context.Object, new System.Web.Routing.RouteData(), controller);
var result = controller.SignUp(rvm) as Task<ActionResult>;
var viewresult = result.Result;
Assert.IsNotNull(result);
}
catch (Exception ex) { string str = ex.ToString(); }
}
原始注册方法,当我运行调试模式,工作正常,但如果从单元测试执行提供了错误。
[HttpPost]
public async Task<ActionResult> SignUp(RegisterViewModel rvm)
{
if (ModelState.IsValid)
{
var appUser = new ApplicationUser();
appUser.UserName = bLayer.GenerateInvestarID(rvm.Email);
appUser.Email = rvm.Email;
appUser.Name = rvm.Name;
appUser.LockoutEnabled = true;
appUser.InstituteCode = "10";
try
{
var result = await UserManager.CreateAsync(appUser, rvm.Password);
if (result.Succeeded)
{
IdentityResult addResult = await UserManager.AddToRoleAsync(appUser.Id, "I");
await SignInManager.SignInAsync(appUser, isPersistent: false, rememberBrowser: false);
string code = await UserManager.GenerateEmailConfirmationTokenAsync(appUser.Id);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = appUser.Id, code = code }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(appUser.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");
return RedirectToAction("Thankyou");
}
else
{
AddErrors(result);
return PartialView("_PartialSignUp", rvm);
}
}
catch(Exception ex)
{
ModelState.AddModelError("CredentialError", ex.Message);
return PartialView("_PartialSignUp", rvm);
}
}
else
{
ModelState.AddModelError("CredentialError", "Invalid Details");
return PartialView("_PartialSignUp", rvm);
}
}
我获得以下错误而IdentityResult addResult =等待UserManager.AddToRoleAsync(appUser.Id, “I”)由上述代码通过单元测试执行。
System.NullReferenceException was caught
_HResult=-2147467261
_message=Object reference not set to an instance of an object.
HResult=-2147467261
IsTransient=false
Message=Object reference not set to an instance of an object.
Source=Microsoft.AspNet.Identity.Core
StackTrace:
at Microsoft.AspNet.Identity.UserManager`2.<AddToRoleAsync>d__83.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at SiteMVC.Controllers.AccountController.<SignUp>d__0.MoveNext()
这是什么问题导致上述错误。
对我来说,它看起来像你需要为'IUserStore.GetRolesAsync'方法'UserManager.AddToRoleAsync'方法建立结果调用'IUserStore.GetRolesAsync'并呼吁角色返回的集合'Contains'方法。由于在单元测试中没有为此方法设置结果,因此它将返回null作为引起此异常发生的默认值。 –