Extending the solution of NKosi to be able to mock any type of object stored in session, first create extensionmethods GetObject and SetObject
public static class SessionExtensions
{
public static T GetObject<T>(this ISession session, string key)
{
var data = session.GetString(key);
if (data == null)
{
return default(T);
}
return JsonConvert.DeserializeObject<T>(data);
}
public static void SetObject(this ISession session, string key, object value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
}
}
Then create a TestHelper method like this:
public static void SetSession(Controller controller, string key = null, object testObject = null)
{
controller.ControllerContext.HttpContext = new DefaultHttpContext();
var mockSession = new Mock<ISession>();
if(testObject != null && key != null)
{
var value = Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(testObject));
mockSession.Setup(s => s.Set(key, It.IsAny<byte[]>())).Callback<string, byte[]>((k, v) => value = v);
mockSession.Setup(s => s.TryGetValue(key, out value)).Returns(true);
}
controller.HttpContext.Session = mockSession.Object;
}
Imagine a controller which retreives a custom object from Session like this:
public IActionResult TestSessionObjects()
{
.....
var test = HttpContext.Session.GetObject<CustomObject>("KeyInSession");
.....
return View();
}
Now you can create a test:
[Fact]
public async void TestSessionObjectsTest()
{
// Arrange
var myController = new MyController();
TestHelpers.SetSession(myController, "KeyInSession", new CustomObject());
// Act
ViewResult result = await myController.TestSessionObjects() as ViewResult;
// Assert
....
}
Now when in your method under test GetObject is called, it will return the object created in the Arrange part.
HttpContext.Session.GetObject<CustomObject>("KeyInSession")
This will also work for e.g. int32. Set it up like:
[Fact]
public async void TestSessionObjectsTestInt()
{
// Arrange
var myController = new MyController();
TestHelpers.SetSession(myController, "AnInt32", 2022);
....
}
When in your method under test the GetObject is called 2022 will be returned:
HttpContext.Session.GetObject<int>("AnInt32")