我正在c#asp.net mvc3中编写一个项目,我有一个如下所示的辅助类:
using System.Collections.Generic;
using System.Web;
namespace CoPrice.Helpers
{
public static class Messages
{
public static IList<Message> All
{
get
{
var list = ((IList<Message>)HttpContext.Current.Session["_messages"]) ?? new List<Message>();
HttpContext.Current.Session["_messages"] = new List<Message>();
return list;
}
}
public static bool Exists
{
get
{
return (((IList<Message>)HttpContext.Current.Session["_messages"]) ?? new List<Message>()).Count > 0;
}
}
public static void Add(MessageType type, string message)
{
Message m = new Message
{
Type = type,
Text = message
};
HttpContext.Current.Session["_messages"] = HttpContext.Current.Session["_messages"] as List<Message> ?? new List<Message>();
((IList<Message>)HttpContext.Current.Session["_messages"]).Add(m);
}
public enum MessageType
{
Info,
Success,
Error
}
public struct Message
{
public MessageType Type;
public string Text;
}
}
}
但是,当我尝试在测试中使用它们时,它会崩溃(导致HttpContext.Current变为null)。如何在测试和应用程序本身中完成这项工作?我不介意必须更改此类以使用除HttpContext.Current之外的其他内容来访问会话,但我希望它具有属性,因此它不能将session-object作为参数。
关于如何解决这个问题的任何想法?
答案 0 :(得分:2)
您需要定义IMessagesProvider并使用DI容器来注入IMessagesProvider的实现。在实际使用中,您将拥有一个使用ASP.Net会话的实现。在测试使用中,你大多会嘲笑它。顺便说一下,你可能不应该有一个静态的消息类。实际上,IMessagesProvider可能会替换您的静态Messages类。
例如:
public class FooController : Controller
{
IMessagesProvider _messages;
public FooController(IMessagesProvider messages)
{
// Your DI container will inject the messages provider automatically.
_messages = messages;
}
public ActionResult Index()
{
ViewData["messages"] = _messages.GetMessages(Session.SessionId);
return View();
}
}
请注意,这是一个非常简单的例子。实际上,您可能还需要一个类,它是驱动视图的模型。快速介绍:
public ActionResult Index()
{
var model = PrepareModel(_messages);
return View(model);
}
“PrepareModel”是您自己的方法,它实例化一个新的模型类,用必要的数据填充它,然后将它发送到您的视图。每个视图定义一个模型类通常是典型的。例如。你有像“SignupFormModel”,“DashboardModel”,“ChatModel”等模型类,这样做也可以让你拥有强类型的视图(很棒)。
答案 1 :(得分:0)
您还可以实现从HttpSessionStateBase类
继承的模拟会话对象答案 2 :(得分:0)
@xanadont是正确的,您需要将Messages
变成普通类。但是(我知道这在某些圈子里是异端),不需要一个一次性的界面和一个完整的DI框架。只需在Messages
类上创建虚拟方法,这样就可以在单元测试中模拟它们,并使用构造函数注入:
public class FooController : Controller
{
Messages _messages;
// MVC will call this ctor
public FooController() : this(new Messages())
{
}
// call this ctor in your unit-tests with a mock object, testing subclass, etc.
public FooController(Messages messages)
{
_messages = messages;
}
}