我正在为asp.net应用程序进行单元测试。由于我目前正在测试的类是如何设计的,它使用多个线程,因此手动设置其中一个线程的语言:
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(HttpContext.Current.Request.UserLanguages[0]);
为了实现这一点,我在运行包含上述代码的类之前,通过在单元测试中使用以下类来模拟httpcontext:
public class HttpContextMock
{
public static HttpContext MockedHttpContext()
{
var httpRequest = new HttpRequest("", "MyUrl", "");
var stringWriter = new StringWriter();
var httpResponse = new HttpResponse(stringWriter);
var httpContext = new HttpContext(httpRequest, httpResponse);
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;
}
现在问题是即使我得到一个有效的httpcontext命令
HttpContext.Current.Request.UserLanguages
始终返回null。
所以我的问题是为了确保UserLanguages至少返回1个条目可以做些什么?
答案 0 :(得分:0)
当您刚刚发现时,模拟出HTTPContext并不容易。
为什么不完全避免这种情况?
而不是
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(HttpContext.Current.Request.UserLanguages[0]);
您可以执行类似
的操作Thread.CurrentThread.CurrentUICulture = _ContextSpecificSettings.Language;
_ContextSpecificSettings
是您自己编码的类的实例。可能是这样的:
class ContextSpecificSettings
{
HTTPContext _HTTPContext;
public ContextSpecificSettings()
{
_HTTPContext = HTTPContext;
}
public string Language // used string but you would of course use here whatever type is used in UserLanguages
{
get { return _HttpContext.Current.Request.UserLanguages[0]; }
}
}
现在,您只需要模拟/存根自己的ContextSpecificSettings类,而不是尝试模拟HTTPContext。这样做要容易得多,因为你需要模拟/存根才能返回你想要在测试中使用的语言。
剩下要做的就是确保包含Thread.CurrentThread.CurrentUICulture
分配的类能够获得ContextSpecificSettings
类的实例。您可以使用简单的构造函数注入来实现。例如:
class SomeThreadUsingClass
{
ContextSpecificSettings _Settings;
public SomeThreadContextUsingClass(ContextSpecificSettings useThisSettingsInstance)
{
_Settings = useThisSettingsInstance;
}
public Int SomeMethodUsingLanguage()
{
// <snip>
Thread.CurrentThread.CurrentUICulture = _Settings.Language;
// <snip>
return Whatever;
}
}
在实际代码中实例化SomeThreadUsingClass
时,将其传递给ContextSpecificSettings
类的(新)实例。在测试中实例化SomeThreadUsingClass
时,您所要做的就是将一个实例传递给ContextSpecificSettings Mock / Stub类。
顺便说一句,这与我在Property.Settings.Default makes it hard to unit test any method that uses it
中描述的技术相同