I’m writing a project in c# asp.net mvc3, and I have a helper-class that looks like this:
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;
}
}
}
However, when I try to use these in a test, it crashes (cause of HttpContext.Current beeing null). How can I make this work both in tests and in the app itself? I don’t mind having to change this class to use something else than HttpContext.Current to access the session, but I want it to have properties as it does, so it can’t take the session-object as a parameter.
Any ideas on how to solve this problem?
You need to define an IMessagesProvider and use an DI container to inject the implementation of the IMessagesProvider. In real use you’ll have an implementation that uses the ASP.Net session. In test use you’ll mostly mock it. BTW, you probably shouldn’t have a static Messages class. In fact, IMessagesProvider will probably replace your static Messages class.
Ex:
Mind you, this is a very simple example. In fact, you probably want one more class which is the model that drives the view. A quick intro:
“PrepareModel” is your very own method that instantiates a new model class, fills it with the necessary data, and then you send it off to your view. It’s typical to have one model class per view defined. E.g. you’d have model classes like “SignupFormModel”, “DashboardModel”, “ChatModel”, etc., Doing so allows you to have strongly-typed views as well (a great thing).