Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you mock the session object collection using Moq

I am using shanselmann's MvcMockHelper class to mock up some HttpContext stuff using Moq but the issue I am having is being able to assign something to my mocked session object in my MVC controller and then being able to read that same value in my unit test for verification purposes.

My question is how do you assign a storage collection to the mocked session object to allow code such as session["UserName"] = "foo" to retain the "foo" value and have it be available in the unit test.

like image 231
rayray2030 Avatar asked Feb 07 '09 19:02

rayray2030


People also ask

What can be mocked with MOQ?

Unit testing is a powerful way to ensure that your code works as intended. It's a great way to combat the common “works on my machine” problem. Using Moq, you can mock out dependencies and make sure that you are testing the code in isolation. Moq is a mock object framework for .

How does MOQ mock work?

Mock objects allow you to mimic the behavior of classes and interfaces, letting the code in the test interact with them as if they were real. This isolates the code you're testing, ensuring that it works on its own and that no other code will make the tests fail.

What is mock test in .NET core?

A mock version of something is an object that can act like the real thing but can be controlled in test code. Moq (pronounced “mok u” or “mock”) is a library available on NuGet that allows mock objects to be created in test code and it also supports . NET Core.


2 Answers

I started with Scott Hanselman's MVCMockHelper, added a small class and made the modifications shown below to allow the controller to use Session normally and the unit test to verify the values that were set by the controller.

/// <summary> /// A Class to allow simulation of SessionObject /// </summary> 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; }     } }  //In the MVCMockHelpers I modified the FakeHttpContext() method as shown below public static HttpContextBase FakeHttpContext() {     var context = new Mock<HttpContextBase>();     var request = new Mock<HttpRequestBase>();     var response = new Mock<HttpResponseBase>();     var session = new MockHttpSession();     var server = new Mock<HttpServerUtilityBase>();      context.Setup(ctx => ctx.Request).Returns(request.Object);     context.Setup(ctx => ctx.Response).Returns(response.Object);     context.Setup(ctx => ctx.Session).Returns(session);     context.Setup(ctx => ctx.Server).Returns(server.Object);      return context.Object; }  //Now in the unit test i can do AccountController acct = new AccountController(); acct.SetFakeControllerContext(); acct.SetBusinessObject(mockBO.Object);  RedirectResult results = (RedirectResult)acct.LogOn(userName, password, rememberMe, returnUrl); Assert.AreEqual(returnUrl, results.Url); Assert.AreEqual(userName, acct.Session["txtUserName"]); Assert.IsNotNull(acct.Session["SessionGUID"]); 

It's not perfect but it works enough for testing.

like image 149
RonnBlack Avatar answered Sep 28 '22 22:09

RonnBlack


Using Moq 3.0.308.2 here is an example of my account controller setup in my unit test:

    private AccountController GetAccountController ()     {       .. setup mocked services..        var accountController = new AccountController (..mocked services..);        var controllerContext = new Mock<ControllerContext> ();       controllerContext.SetupGet(p => p.HttpContext.Session["test"]).Returns("Hello World");       controllerContext.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(_testEmail);       controllerContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);       controllerContext.SetupGet(p => p.HttpContext.Response.Cookies).Returns(new HttpCookieCollection ());        controllerContext.Setup (p => p.HttpContext.Request.Form.Get ("ReturnUrl")).Returns ("sample-return-url");       controllerContext.Setup (p => p.HttpContext.Request.Params.Get ("q")).Returns ("sample-search-term");        accountController.ControllerContext = controllerContext.Object;        return accountController;     } 

then within your controller method the following should return "Hello World"

string test = Session["test"].ToString (); 
like image 38
Todd Smith Avatar answered Sep 28 '22 22:09

Todd Smith