简体   繁体   中英

Accessing Session via ICacheClient during unit testing ServiceStack Service

We've got a ServiceStack 3.9.x service that we're trying to unit test end-to-end (via an in-process service host and accessing it via C# native clients), and we're running into a snag where it seems that the session is not accessible via the means we typically use to access it when running this way.

We typically access the current session (using servicestack's built-in system and custom AuthSession and providers, which all works fine running in IIS against an AppHost derived from AppHostBase) using this:

EndpointHost.AppHost.TryResolve<ICacheClient>().SessionAs<SsoUserSession>();

However, when trying to access this in unit testing (against an AppHost derived from AppHostHttpListenerBase), we get an exception thrown trying to get at the session: "Only ASP.NET Requests accessible via Singletons are supported" which appears to be a hard-coded error in the SessionFeature.

So the question is this: can one access sessions via the cache provider when unit testing via a service host derived from AppHostHttpListenerBase? And if so, how?

I've run into this before too.

The way I handle it is create create something like an extension method to get the session from the cache client that just calls the base, but before calling the base..check the IoC container for the session first. If it's there, just use that instead, and I just inject the session I want to use when testing.

This is used somewhere in servicestack but I can't seem to find the method that does it...anyway an extension method could look something like this

public static MyTypedSession GetMyTypedSession(this ICacheClient cache)
{
    var typedSession = ServiceStackHost.Instance.Container.TryResolve<MyTypedSession>();

    if (typedSession != default(MyTypedSession))
        return typedSession;

    return cache.SessionAs<MyTypedSession>();
}

Then instead of calling SessionAs in your code to get the typed session, you would just call GetMyTypedSession , and it would work fine for testing, so long as you Register your fake MyTypedSession

Here's some c# psuedo test method

public void SomeTestMethod()
{
    var session = new MyTypedSession { IsAuthenticated = true; };

    //get your container and register the session
    container.Register(session);

    var someValue = TestCodeThatUsesASession();

    Assert(someValue);
}

I'm unsure what kinda delay looking in the IoC container everytime you need a session is though.

Sorta strange to add that code just for testing but oh well, works for me and save me time :).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM