Search code examples
c#asp.net-mvcvisual-studionunitasp.net-identity

Asp.net Identity create User without HttpContext


I am trying to run some Unit Tests and I'd like to be able to create a User using the Asp.Net Identity framework but it needs an HttpContextBase. So, I decided to use another Stack Overflow thread suggestion and mock one up. It looks like this:

    public HttpContext FakeHttpContext
    {
        get
        {
            var httpRequest = new HttpRequest("", "http://stackoverflow/", "");
            var stringWriter = new StringWriter();
            var httpResponce = new HttpResponse(stringWriter);
            var httpContext = new HttpContext(httpRequest, httpResponce);

            var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
                                                    new HttpStaticObjectsCollection(), 10, true,
                                                    HttpCookieMode.AutoDetect,
                                                    SessionStateMode.InProc, false);

            httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
                                        BindingFlags.NonPublic | BindingFlags.Instance,
                                        null, CallingConventions.Standard,
                                        new[] { typeof(HttpSessionStateContainer) },
                                        null)
                                .Invoke(new object[] { sessionContainer });

            return httpContext;
        }
    }

    public HttpContextBase FakeHttpContextBase
    {
        get
        {
            return (new HttpContextWrapper(this.FakeHttpContext));
        }
    }

This works fine, until it gets to the Owin stuff, at which point it fails.

The Startup doesn't run for the Unit Tests. This is my Startup:

    [assembly: OwinStartupAttribute(typeof(MyProject.Startup))]
    namespace MyProject
    {
        public partial class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                ConfigureAuth(app);
            }
        }

        public void ConfigureAuth(IAppBuilder app)
        {
            // Configure the db context and user manager to use a single instance per request
            app.CreatePerOwinContext(DataContext.Create);
            app.CreatePerOwinContext<IdentityManager>(IdentityManager.Create);

            // More Identity Stuff...
        }
    }

How can I call:

    var result = await IdentityManager.Instance(this.FakeHttpContextBase).CreateAsync(user, password);

And get the Startup to run so I can create this User?

Or am I completely on the wrong path on this?

I am trying to run Unit Tests with NUnit in Visual Studio.

Note: Please don't tell me I should be using a Mock Library. Linq to Object does not work the same as Linq to Entity and I am trying to test my actual code I will be using in my application, which means testing it against an actual database. That is all working fine. This is solely about how to create a User.


Solution

  • Figured out a different way to instantiate the User Manager with just my DataContext.

    This is the final test result:

        private async void SeedUser()
        {
            using (var context = new DataContext()) {
                var newUser = new User() { UserName = "[email protected]", Email = "[email protected]", Name = "Buzz Lightyear" };
    
                var userManager = new IdentityManager(new UserStore<User>(context));
    
                var result = await userManager.CreateAsync(newUser, "infinityandbeyond");
    
                if (!result.Succeeded) {
                    Assert.Fail("Failed to set up User for TestBase.");
                }
    
                var user = context.Users.FirstOrDefault();
    
                if (user == null) {
                    Assert.Fail("The User was not found in the database.");
                }
    
                this.UserId = user.Id;
            }
        }