我有一个正在运行的应用程序,我现在需要为其添加一整套单元测试。当前代码存储用户信息如下:
HttpContext.Current.Session["UserInfo"] = userData;
我使用最小起订量进行测试,我的单元测试具有以下代码:
var server = new Mock<HttpServerUtilityBase>(MockBehavior.Loose);
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
var context = new Mock<HttpContextBase>();
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
context.SetupGet(x => x.Server).Returns(server.Object);
var controller = new LoginController();
controller.ControllerContext = new ControllerContext(
context.Object,
new RouteData(),
controller);
JsonResult result = controller.LoginUser(
new LoginHelper {
userName = "myusername",
password = "invalidpassword"
}
) as JsonResult;
当然,当我到达登录进程尝试创建 session 数据的位置时,我得到一条“对象引用未设置到对象实例”。错误,因为 HttpContext.Current 为 null。
一些研究表明,使用 Current 与 MSTest 并不完全兼容,因此我了解我可能需要更改存储/加载用户信息的方式。不过,我想要一些关于该走哪条路的建议。
如果有人建议我如何让我的单元测试工作,或者使用不同的方法来存储用户信息以使其与单元测试更兼容,我将不胜感激。
最佳答案
这是我想出的解决方案。它是我在不同地方找到的一些东西的组合,包括这里:
首先,我创建了 2 个类.. MockHttpSession 和 MockHelpers
public class MockHttpSession : HttpSessionStateBase
{
Dictionary<string, object> m_SessionStorage = new Dictionary<string, object>();
public override object this[string name]
{
get { return m_SessionStorage[name]; }
set { m_SessionStorage[name] = value; }
}
public override void Abandon()
{
// Do nothing
}
}
public class MockHelpers
{
public static HttpContext FakeHttpContext()
{
var httpRequest = new HttpRequest("", "http://localhost/", "");
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);
SessionStateUtility.AddHttpSessionStateToContext(httpContext, sessionContainer);
return httpContext;
}
}
然后我更改了单元测试代码以使用这些:
var server = new Mock<HttpServerUtilityBase>(MockBehavior.Loose);
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
var session = new MockHttpSession();
var context = new Mock<HttpContextBase>();
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
context.SetupGet(x => x.Server).Returns(server.Object);
context.SetupGet(x => x.Session).Returns(session);
HttpContext.Current = MockHelpers.FakeHttpContext();
var controller = new LoginController();
controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
JsonResult result = controller.LoginUser(new LoginHelper { userName = "MyUserName", password = ""InvalidPassword }) as JsonResult;
这能够使用有效和无效密码成功测试代码。
感谢大家的帮助
关于c# - 为 HttpContext.Current.Session 编写单元测试时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29078902/