Reputation: 2218
Below is piece of the code of controller method(c#) :-
public ActionResult SelectProduct(string ProdName, int Block, int ProductAddressId = 0)
{
if (ProductAddressId == 0 && Block == 1 && System.Web.HttpContext.Current.Session["ReturnProductAddressID"] != null)
{
ProductAddressId = (int)System.Web.HttpContext.Current.Session["ReturnProductAddressID"];
}
//other stuffs………
}
Below is unit test method :-
[TestMethod]
public void SelectProduct_Condition1_Test()
{
//Arrange
var controller = new ProductController();
var prodName = string.Empty;
var block = 1;
var productAddressId = 0;
//section 1
/*var mockControllerContext = new Mock<ControllerContext>();
var mockSession = new Mock<HttpSessionStateBase>();
mockSession.SetupGet(s => s["ReturnProductAddressID"]).Returns("1");
mockControllerContext.Setup(p => p.HttpContext.Session).Returns(mockSession.Object);*/
//section 2
/*int sessionValue = 1;
var mockControllerContext = new Mock<ControllerContext>();
var mockSession = new Mock<HttpSessionStateBase>();
mockSession.SetupSet(s => s["ReturnProductAddressID"] = It.IsAny<int>()).Callback((string name, object val) => sessionValue = (int)val);
mockSession.SetupGet(s => s["ReturnProductAddressID"]).Returns(() => sessionValue);
mockControllerContext.Setup(p => p.HttpContext.Session).Returns(mockSession.Object);*/
//Act
var actual = controller.SelectProduct(prodName,block,productAddressId);
}
I want to ask how can i test or mock the session value up side on my action method(in if condition) ?
I have tried certain things in section 1 and section 2(commented section in unit test method above).But nothing is working for that.
So can anyone let me know how to do unit test for sessions ?
EDIT:
Nothing the above stuff working instead of below :-
System.Web.HttpContext.Current.Session["ReturnProductAddressID"] = "12";
means if i set the session value directly in unit test method.But i want to know will it be correct approach ?
Upvotes: 8
Views: 10135
Reputation: 1
To be honest: mocking Session vars or using 'the real deal' by hooking into the current session keeps being nasty to do. When having lots of HttpContext.Session vars in your code - yes, you can have an opinion about it - makes testing them 'hard' to do.
My solution is using ViewBags as much as possible and keep result values you want to test into those ViewBags and ignore the null errors from the HttpContext.Session vars. If you really want to test some of them and their values, put those values in ViewBags and test those in your viewResult.
By using proper try catches in my real code, the nulls on Session vars will be ígnored and when needed I'll check the values of ViewBags in viewResult.
Is this the best solution? Probably not, no, definitely not but it kept my pace going and solved the need: getting the controllers running and keeping an eye on the values I want in ViewBags.
Example code:
// Arrange
TarotCards.Controllers.ProverbsController controller = new
TarotCards.Controllers.ProverbsController();
// Act
ActionResult result = controller.IndexThrow("KeeperHelp");
// Assert
Assert.IsInstanceOfType(result, typeof(ViewResult));
ViewResult viewResult = result as ViewResult;
if (viewResult != null)
{
string sProverb = viewResult.ViewData["Proverb"].ToString();
Assert.IsTrue(sProverb.Contains("Help on Keeper"));
// Assert content of viewResult.
}
Upvotes: 0
Reputation: 7525
You can use Mock. Here is how I have done before.
Download updated MoQ https://www.nuget.org/packages/moq
Moc session for the controller
var mockControllerContext = new Mock<ControllerContext>();
var mockSession = new Mock<HttpSessionStateBase>();
mockSession.SetupGet(s => s["ReturnProductAddressID"]).Returns("123"); //somevalue
mockControllerContext.Setup(p => p.HttpContext.Session).Returns(mockSession.Object);
Register mockControllerContext for controller
var controller = new YourController();
controller.ControllerContext = mockControllerContext.Object;
Finally Act
var actual = controller.SelectProduct(YourModel);
So, your code would be something like this.
[TestMethod]
public void SelectProduct_Condition1_Test()
{
var prodName = string.Empty;
var block = 1;
var productAddressId = 0;
var mockControllerContext = new Mock<ControllerContext>();
var mockSession = new Mock<HttpSessionStateBase>();
mockSession.SetupGet(s => s["ReturnProductAddressID"]).Returns("123"); //somevalue
mockControllerContext.Setup(p => p.HttpContext.Session).Returns(mockSession.Object);
var controller = new ProductController();
controller.ControllerContext = mockControllerContext.Object;
//Act
var actual = controller.SelectProduct(prodName, block, productAddressId);
}
Upvotes: 18