我们在服务层上面有一个代码来获取sessionID并传递给外部API进行会话关联。
public static string GetCorrelationSession()
{
if (HttpContext.Current != null && HttpContext.Current.Session != null)
{
//do some check and
if (!HttpContext.Current.User.Identity.IsAuthenticated | userContext == null)
return HttpContext.Current.Session.SessionID;
}
else
{
return null
}
}
我试过并且也搜索了我们如何模拟httpcontext.current.session.sessionID,但所有示例似乎都是asp.net控制器。
在单元测试中模拟或初始化httpcontext.current.session.sessionID的最佳方法是什么?
答案 0 :(得分:4)
始终避免像使用静态方法一样,因为很难模仿它们。您需要弄清楚如何获取会话ID。您可以创建一个抽象,给出当前会话ID,如下所示:
public interface ISessionProvider
{
string GetCorrelationSession();
}
然后有一个实现AspNetSessionProvider
,如下所示:
public interface AspNetSessionProvider : ISessionProvider
{
public string GetCorrelationSession()
{
// Here you put how to get the current session Id.
}
}
那么如何使用呢?您可以使用以下解决方案之一:
如果您正在使用依赖注入,则通过其控制器将ISessionProvider
注入您需要的每个控制器或服务中。因为模拟界面并不困难,所以使用这个界面的所有类都可以很容易地测试。
仅当许多服务或控制器需要访问ISessionProvider
时才使用此解决方案,因此它成为跨领域提供商。它类似于Property Injection(依赖注入),但如果没有设置则默认实现。因此,您创建另一个新类,我们将其命名为SessionProvider
,因此其代码如下所示:
public class SessionProvider
{
private static readonly Lazy<ISessionProvider> InstanceProvider = new Lazy<ISessionProvider>(() => GetSessionProviderFromFactory() ?? new AspNetSessionProvider());
private static Func<ISessionProvider> _factory;
public static ISessionProvider Instance
{
get { return InstanceProvider.Value; }
}
public static void SetSessionProvider(Func<ISessionProvider> sessionProviderFactory)
{
if (_factory != null)
{
throw new InvalidOperationException("The session provider factory is already initialized");
}
if (sessionProviderFactory == null)
{
throw new InvalidOperationException("The session provider factory value can't be null");
}
_factory = sessionProviderFactory;
}
private static ISessionProvider GetSessionProviderFromFactory()
{
ISessionProvider sessionProvider = null;
if (_factory != null)
{
sessionProvider = _factory();
if (sessionProvider == null)
{
throw new InvalidOperationException("The session factory, when it is set, must not return a null isntance.");
}
}
return sessionProvider;
}
}
在您的应用程序代码中,只要您需要访问会话ID,就可以通过调用此行来使用它:
SessionProvider.Instance.GetCorrelationSession();
在单元测试的测试夹具设置中,您可以使用以下代码设置模拟实例:
var mock = new Mock<ISessionProvider>();
// Setup the mock
SessionProvider.SetSessionProvider(() => mock.Object);