2

저는 ASP.Net MVCIdentity을 처음 사용합니다.ASP.Net에서 단위 테스트를 실행하는 동안 오류가 발생했습니다 .Net.Net Identity를 사용하는 MVC 레지스터 코드

다음 단위 테스트 방법이 있습니다.

[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(); } 
} 

디버그 모드를 실행하면 정상적으로 작동하지만 단위 테스트에서 실행하면 오류가 발생하는 원본 SignUp 메서드입니다. I가 다음 오류 얻을

[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() 

무엇이 잘못 되었습니까?

+0

는'IUserStore.GetRolesAsync'를 호출하고 역할의 반환 컬렉션'Contains' 메소드를 호출 보인다. 단위 테스트에서이 메소드에 대한 결과가 없으므로이 예외를 발생시키는 기본값으로 null을 리턴합니다. –

답변

3

IUserStore.GetRolesAsync 메서드의 결과를 설정해야하는 것처럼 보입니다.

UserManager.AddToRoleAsync 메서드는 IUserStore.GetRolesAsync를 호출하고 반환 된 역할 컬렉션에서 '포함'메서드를 호출합니다.

단위 테스트에서이 메서드를 설정 한 결과가 없으므로이 예외가 발생하게하는 기본값으로 null을 반환합니다.

아래 코드는 IUserStore.GetRolesAsync에 대한 결과로 빈 역할 목록을 반환하도록 설정 한 코드입니다. 당신이 UserManager.AddToRoleAsync` 방법`등`IUserStore.GetRolesAsync` 방법에 대한 설정 결과에 필요한처럼 나에게

[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>>(); 

     var roles = new List<string>(); // Populate this list as per your need. 

     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)); 

     //Setting up the result for GetRoleAsync method to return roles collection. 
     store.As<IUserRoleStore<ApplicationUser>>().Setup(x => x.GetRolesAsync(It.IsAny<ApplicationUser>())).ReturnsAsync(roles); 

     //Rest of the unit test code 
    } 
    catch (Exception ex) { string str = ex.ToString(); } 
} 
+0

Chetan에게 감사드립니다. 그것은 내 문제를 해결했다. – rikencpatel

+0

정말 놀랍지 만 다른 곳에서는 이것을 어떻게 설정할 수 없습니까. 고맙습니다! – Tim