This project has moved. For the latest updates, please go here.

How to unit test code that uses OWIN Cookie Authenthication

Dec 8, 2014 at 6:55 PM
I am cross-posting this from Stack Overflow after a seemingly related question was brought up on the Thinktecture.IdentityServer.v3 gitter, with the thought that perhaps the community here might be more qualified to give an answer.

Microsoft.Owin.Testing library seems to be a great library to let you test your web application in-memory. However, my site requires authentication before accessing resources which has complicated writing test code.

Is there a convenient way to "mock" authentication when using Microsoft.Owin.Testing?

I would like my unit tests to not need to hit an out-of-process STS and I would prefer not to need to write code that programmatically signs in against an in-memory STS (such as Thinktecture.IdentityServer.v3).

The easiest solution I come up with is to disable the authentication code for the unit tests, of which I am not a fan. Then I would also need to figure out how to otherwise inject the Principal for the code that depends on it.

I am using OpenID Connect with Cookie Authentication. Here is a contained example. The configuration strings for the OpenId Connect would need to be filled in for an actual server.
[Test]
public async void AccessAuthenthicatedResourceTest()
{
    const string ClientId = "";
    const string RedirectUri = "";
    const string Authority = "";

    TestServer server = TestServer.Create(
        app =>
            {
                //Configure Open ID Connect With Cookie Authenthication
                app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
                app.UseCookieAuthentication(new CookieAuthenticationOptions());
                app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
                    {
                    ClientId = ClientId,
                    RedirectUri = RedirectUri,
                    Authority = Authority
                    });

                // Requires Authentication
                app.Use(
                    async ( context, next ) =>
                        {
                            var user = context.Authentication.User;
                            if ( user == null
                                 || user.Identity == null
                                 || !user.Identity.IsAuthenticated )
                            {
                                context.Authentication.Challenge();
                                return;
                            }

                            await next();
                        } );

                app.Run( async context => await context.Response.WriteAsync( "My Message" ) );
            } );


    //Do or Bypass authenthication

    HttpResponseMessage message = await server.CreateRequest( "/" ).GetAsync();

    Assert.AreEqual("My Message", await message.Content.ReadAsStringAsync());
}
Coordinator
Dec 8, 2014 at 7:06 PM
We recomend Microsoft.Owin.Testing be used for testing individual components, not entire applications. To test authenticated end-points in your app try supplying a mock auth middleware that assignes the request user with a test user.

Testing your entire app together sounds like integration testing that you'd do manually or in a staging environment.