ASP / NET MVC: Session Controllers? Tantalizing?

I read some answers here: testing views and controllers and mockery, but I still can't figure out how to test an ASP.NET MVC controller that reads and sets Session values ​​(or any other context-based variables.) How to provide a context ( session) for my testing methods? Mocks us? Anyone have any examples? Basically, I would like to fake a session before I call the controller method, and the controller will use this session. Any ideas?

+43
unit-testing asp.net-mvc session mocking
Oct 06 '08 at 21:49
source share
7 answers

Send Steven Walter a message in the Faking the Controller Context:

ASP.NET MVC Tip # 12 - Counterfeit Controller Context

[TestMethod] public void TestSessionState() { // Create controller var controller = new HomeController(); // Create fake Controller Context var sessionItems = new SessionStateItemCollection(); sessionItems["item1"] = "wow!"; controller.ControllerContext = new FakeControllerContext(controller, sessionItems); var result = controller.TestSession() as ViewResult; // Assert Assert.AreEqual("wow!", result.ViewData["item1"]); // Assert Assert.AreEqual("cool!", controller.HttpContext.Session["item2"]); } 
+43
Oct 26 '08 at 18:03
source share

The ASP.NET MVC framework is not very friendly (or rather requires too many settings to fake correctly and causes too much friction when testing, IMHO) due to the use of abstract base classes instead of interfaces. We managed to write abstractions for each request and session storage. We keep these abstractions very light, and then our controllers depend on these abstractions for each request or for storage in the session.

For example, here we manage auth files. We have ISecurityContext:

 public interface ISecurityContext { bool IsAuthenticated { get; } IIdentity CurrentIdentity { get; } IPrincipal CurrentUser { get; set; } } 

With a specific implementation, for example:

 public class SecurityContext : ISecurityContext { private readonly HttpContext _context; public SecurityContext() { _context = HttpContext.Current; } public bool IsAuthenticated { get { return _context.Request.IsAuthenticated; } } public IIdentity CurrentIdentity { get { return _context.User.Identity; } } public IPrincipal CurrentUser { get { return _context.User; } set { _context.User = value; } } } 
+12
Oct 06 '08 at 22:02
source share

With MVC RC 1, the ControllerContext wraps an HttpContext and exposes it as a property. This makes mocking a lot easier. To make fun of a session variable using Moq, follow these steps:

 var controller = new HomeController(); var context = MockRepository.GenerateStub<ControllerContext>(); context.Expect(x => x.HttpContext.Session["MyKey"]).Return("MyValue"); controller.ControllerContext = context; 

See Scott Ghoul's post for more details.

+8
Feb 17 '09 at 18:00
source share

I laughed quite easily. Here's an example of bullying httpContextbase (containing request, session, and response objects) using moq.

 [TestMethod] public void HowTo_CheckSession_With_TennisApp() { var request = new Mock<HttpRequestBase>(); request.Expect(r => r.HttpMethod).Returns("GET"); var httpContext = new Mock<HttpContextBase>(); var session = new Mock<HttpSessionStateBase>(); httpContext.Expect(c => c.Request).Returns(request.Object); httpContext.Expect(c => c.Session).Returns(session.Object); session.Expect(c => c.Add("test", "something here")); var playerController = new NewPlayerSignupController(); memberController.ControllerContext = new ControllerContext(new RequestContext(httpContext.Object, new RouteData()), playerController); session.VerifyAll(); // function is trying to add the desired item to the session in the constructor //TODO: Add Assertions } 

Hope this helps.

+5
Oct. 06 '08 at 22:59
source share

Scott Hanselman has a post on how to create a quickapp file download with MVC and discusses the exchange and specific addresses of "How to mock things that are not mocking."

+2
Oct 06 '08 at 22:22
source share

I used the following solution - creating a controller that all my other controllers inherit from.

 public class TestableController : Controller { public new HttpSessionStateBase Session { get { if (session == null) { session = base.Session ?? new CustomSession(); } return session; } } private HttpSessionStateBase session; public class CustomSession : HttpSessionStateBase { private readonly Dictionary<string, object> dictionary; public CustomSession() { dictionary = new Dictionary<string, object>(); } public override object this[string name] { get { if (dictionary.ContainsKey(name)) { return dictionary[name]; } else { return null; } } set { if (!dictionary.ContainsKey(name)) { dictionary.Add(name, value); } else { dictionary[name] = value; } } } //TODO: implement other methods here as needed to forefil the needs of the Session object. the above implementation was fine for my needs. } } 

Then use the code as follows:

 public class MyController : TestableController { } 
+2
Mar 25 2018-12-25T00:
source share

Since HttpContext is static, I use Typemock Isolator to mock it, Typemock also has an add-in created for ASP.NET unit testing called Ivonna .

0
Apr 24 '09 at 9:01
source share



All Articles