Asp.net mvc 对使用ASP.Net标识的ASP.Net MVC注册代码运行单元测试时出错

Asp.net mvc 对使用ASP.Net标识的ASP.Net MVC注册代码运行单元测试时出错,asp.net-mvc,unit-testing,asp.net-identity,vs-unit-testing-framework,Asp.net Mvc,Unit Testing,Asp.net Identity,Vs Unit Testing Framework,我不熟悉ASP.Net MVC和Identity 我有下面的单元测试方法 [TestMethod] public void SignUp() { try { var dummyUser = new ApplicationUser() { UserName = "xyz", Email = "xyz@gmail.com" }; ViewModels.RegisterViewModel rvm = new ViewModels.RegisterVie

我不熟悉
ASP.Net MVC
Identity

我有下面的单元测试方法

[TestMethod]
public void SignUp()
{
    try
    {
        var dummyUser = new ApplicationUser() { UserName = "xyz", Email = "xyz@gmail.com" };

        ViewModels.RegisterViewModel rvm = new ViewModels.RegisterViewModel { Name = "abc", Email = "abc@yahoo.com", 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(); }
}
[TestMethod]
公开无效注册()
{
尝试
{
var dummyUser=newapplicationuser(){UserName=“xyz”,Email=“xyz@gmail.com" };
ViewModels.RegisterViewModel rvm=新的ViewModels.RegisterViewModel{Name=“abc”,电子邮件=”abc@yahoo.com,Password=“123456”};

var store=new Mock对我来说,似乎需要为IUserStore.GetRolesAsync方法设置结果

UserManager.AddToRoleAsync方法调用IUserStore.GetRolesAsync,并对返回的角色集合调用“Contains”方法

由于在单元测试中没有为此方法设置结果,因此它会返回null作为默认值,这导致了此异常的发生

下面是我为
IUserStore.GetRolesAsync
设置结果以返回空角色列表的代码

[TestMethod]
public void SignUp()
{
    try
    {
        var dummyUser = new ApplicationUser() { UserName = "xyz", Email = "xyz@gmail.com" };

        ViewModels.RegisterViewModel rvm = new ViewModels.RegisterViewModel { Name = "abc", Email = "abc@yahoo.com", 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(); }
}
[TestMethod]
公开无效注册()
{
尝试
{
var dummyUser=newapplicationuser(){UserName=“xyz”,Email=“xyz@gmail.com" };
ViewModels.RegisterViewModel rvm=新的ViewModels.RegisterViewModel{Name=“abc”,电子邮件=”abc@yahoo.com,Password=“123456”};
var store=newmock();
var roles=new List();//根据需要填充此列表。
store.As()
.Setup(x=>x.FindByIdAsync(It.IsAny()))
.ReturnsAsync(新的ApplicationUser(){Id=“Id”});
Setup(x=>x.CreateAsync(dummyUser)).Returns(Task.FromResult(IdentityResult.Success));
//设置GetRoleAsync方法的结果以返回角色集合。
store.As().Setup(x=>x.GetRolesAsync(It.IsAny()).ReturnsAsync(角色);
//单元测试代码的其余部分
}
catch(异常ex){string str=ex.ToString();}
}

在我看来,您似乎需要将
IUserStore.GetRolesAsync
方法的结果设置为
UserManager.AddToRoleAsync
方法调用
IUserStore.GetRolesAsync
和调用
包含返回的角色集合上的
方法。因为在单元测试中没有为该方法设置结果,所以它返回默认值为null,导致出现此异常。令人惊讶的是,我在其他任何地方都找不到如何设置此异常。谢谢!
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()
[TestMethod]
public void SignUp()
{
    try
    {
        var dummyUser = new ApplicationUser() { UserName = "xyz", Email = "xyz@gmail.com" };

        ViewModels.RegisterViewModel rvm = new ViewModels.RegisterViewModel { Name = "abc", Email = "abc@yahoo.com", 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(); }
}