– Request.GetOwinContext returns null within unit test – how to test OWIN authentication within a unit test

I am currently trying to unit test the authentication for a new WebAPI project I am writing using OWIN to authenticate, and I am having problems with running it in a unit test context.

This is my test method:

public void TestRegister()
    using (WebApp.Start<Startup>("localhost/myAPI"))
    using (AccountController ac = new AccountController()
            Request = new System.Net.Http.HttpRequestMessage
                (HttpMethod.Post, "http://localhost/myAPI/api/Account/Register")
        var result = ac.Register(new Models.RegisterBindingModel()
            Email = "",
            Password = "Pass@word1",
            ConfirmPassword = "Pass@word1"

I'm getting an AggregateException on getting the .Result with the following inner exception:

Result Message: 
Test method myAPI.Tests.Controllers.AccountControllerTest.TestRegister 
    threw exception: 
System.ArgumentNullException: Value cannot be null.
Parameter name: context
Result StackTrace:  
at Microsoft.AspNet.Identity.Owin.OwinContextExtensions
    .GetUserManager[TManager](IOwinContext context)
at myAPI.Controllers.AccountController.get_UserManager()

I have confirmed via debugging that my Startup method is being called, calling ConfigurAuth:

public void ConfigureAuth(IAppBuilder app)
    HttpConfiguration config = new HttpConfiguration();

    // Configure the db context and user manager to use a single 
    //  instance per request

    // Enable the application to use a cookie to store information for 
    //  the signed in user
    //  and to use a cookie to temporarily store information about a 
    //  user logging in with a third party login provider
    app.UseCookieAuthentication(new CookieAuthenticationOptions());

    // Configure the application for OAuth based flow
    PublicClientId = "self";
    OAuthOptions = new OAuthAuthorizationServerOptions
        TokenEndpointPath = new PathString("/Token"),
        Provider = new ApplicationOAuthProvider(PublicClientId),
        AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
        AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
        AllowInsecureHttp = true

    // Enable the application to use bearer tokens to authenticate users

I've tried a few things, but nothing seems to work – I can never get an OWIN context. The test is failing on the following code:

// POST api/Account/Register
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    var user = new ApplicationUser() 
       { UserName = model.Email, Email = model.Email };

    IdentityResult result = await UserManager.CreateAsync(user, model.Password);

    if (!result.Succeeded)
        return GetErrorResult(result);

    return Ok();

This calls the UserManager property:

public ApplicationUserManager UserManager
        return _userManager ?? Request.GetOwinContext()
    private set
        _userManager = value;

It fails on:

return _userManager ?? Request.GetOwinContext()

with a NullReferenceExceptionRequest.GetOwinContext is returning null.

So my question is: am I approaching this wrong? Should I just be testing the JSON responses? Or is there a good way to "internally" test OWIN authentication?

Best Solution

GetOwinContext calls context.GetOwinEnvironment(); which is

  private static IDictionary<string, object> GetOwinEnvironment(this HttpContextBase context)
        return (IDictionary<string, object>) context.Items[HttpContextItemKeys.OwinEnvironmentKey];

and HttpContextItemKeys.OwinEnvironmentKey is a constant "owin.Environment" So if you are add that in your httpcontext's Items, it will work.

var request = new HttpRequest("", "", "rUrl=")
        ContentEncoding = Encoding.UTF8  //UrlDecode needs this to be set

    var ctx = new HttpContext(request, new HttpResponse(new StringWriter()));

    //Session need to be set
    var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
        new HttpStaticObjectsCollection(), 10, true,
        SessionStateMode.InProc, false);
    //this adds aspnet session
    ctx.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
        BindingFlags.NonPublic | BindingFlags.Instance,
        null, CallingConventions.Standard,
        new[] { typeof(HttpSessionStateContainer) },
        .Invoke(new object[] { sessionContainer });

    var data = new Dictionary<string, object>()
        {"a", "b"} // fake whatever  you need here.

    ctx.Items["owin.Environment"] = data;