ASP.NET MVC unit test controller with HttpContext

前端 未结 5 1310
攒了一身酷
攒了一身酷 2020-11-28 07:21

I am trying to write a unit test for my one controller to verify if a view was returned properly, but this controller has a basecontroller that accesses the HttpContext.Curr

相关标签:
5条回答
  • 2020-11-28 07:30

    You should probably use an ActionFilter instead of a base class for this sort of thing

    [UserIdBind]
    public class IndexController : Controller
    {
        public ActionResult Index()
        {
            return View("Index.aspx");
        }
    }
    
    0 讨论(0)
  • 2020-11-28 07:33

    I'd checkout the ASP.NET-MVC book listed here -- toward the end, there is a good section on Mocking framewors -- http://www.hanselman.com/blog/FreeASPNETMVCEBookNerdDinnercomWalkthrough.aspx

    0 讨论(0)
  • 2020-11-28 07:36

    If you are using Typemock, you can do this:

    Isolate.WhenCalled(()=>controller.HttpContext.Current.Session["UserID"])
    .WillReturn("your id");
    

    The test code will look like:

    [TestMethod]
    public void Retrieve_IndexTest()
    {
        // Arrange
        const string expectedViewName = "Index";
    
        IndexController controller = new IndexController();
        Isolate.WhenCalled(()=>controller.HttpContext.Current.Session["UserID"])
        .WillReturn("your id");
        // Act
        var result = controller.Index() as ViewResult;
    
        // Assert
        Assert.IsNotNull(result, "Should have returned a ViewResult");
        Assert.AreEqual(expectedViewName, result.ViewName, "View name should have been {0}", expectedViewName);
    }
    
    0 讨论(0)
  • 2020-11-28 07:45

    Snippet:

    var request = new SimpleWorkerRequest("/dummy", @"c:\inetpub\wwwroot\dummy", "dummy.html", null, new StringWriter());
    var context = new HttpContext(request);
    SessionStateUtility.AddHttpSessionStateToContext(context, new TestSession());
    HttpContext.Current = context;
    

    Implementation of TestSession():

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web.SessionState;
    
    namespace m1k4.Framework.Test
    {
        public class TestSession : IHttpSessionState
        {
            private Dictionary<string, object> state = new Dictionary<string, object>();
    
            #region IHttpSessionState Members
    
            public void Abandon()
            {
                throw new NotImplementedException();
            }
    
            public void Add(string name, object value)
            {
                this.state.Add(name, value);
            }
    
            public void Clear()
            {
                throw new NotImplementedException();
            }
    
            public int CodePage
            {
                get
                {
                    throw new NotImplementedException();
                }
                set
                {
                    throw new NotImplementedException();
                }
            }
    
            public System.Web.HttpCookieMode CookieMode
            {
                get
                {
                    throw new NotImplementedException();
                }
            }
    
            public void CopyTo(Array array, int index)
            {
                throw new NotImplementedException();
            }
    
            public int Count
            {
                get
                {
                    throw new NotImplementedException();
                }
            }
    
            public System.Collections.IEnumerator GetEnumerator()
            {
                throw new NotImplementedException();
            }
    
            public bool IsCookieless
            {
                get
                {
                    throw new NotImplementedException();
                }
            }
    
            public bool IsNewSession
            {
                get
                {
                    throw new NotImplementedException();
                }
            }
    
            public bool IsReadOnly
            {
                get
                {
                    throw new NotImplementedException();
                }
            }
    
            public bool IsSynchronized
            {
                get
                {
                    throw new NotImplementedException();
                }
            }
    
            public System.Collections.Specialized.NameObjectCollectionBase.KeysCollection Keys
            {
                get
                {
                    throw new NotImplementedException();
                }
            }
    
            public int LCID
            {
                get
                {
                    throw new NotImplementedException();
                }
                set
                {
                    throw new NotImplementedException();
                }
            }
    
            public SessionStateMode Mode
            {
                get
                {
                    throw new NotImplementedException();
                }
            }
    
            public void Remove(string name)
            {
                this.state.Remove(name);
            }
    
            public void RemoveAll()
            {
                this.state = new Dictionary<string, object>();
            }
    
            public void RemoveAt(int index)
            {
                throw new NotImplementedException();
            }
    
            public string SessionID
            {
                get
                {
                    return "Test Session";
                }
            }
    
            public System.Web.HttpStaticObjectsCollection StaticObjects
            {
                get
                {
                    throw new NotImplementedException();
                }
            }
    
            public object SyncRoot
            {
                get
                {
                    throw new NotImplementedException();
                }
            }
    
            public int Timeout
            {
                get
                {
                    return 10;
                }
                set
                {
                    throw new NotImplementedException();
                }
            }
    
            public object this[int index]
            {
                get
                {
                    throw new NotImplementedException();
                }
                set
                {
                    throw new NotImplementedException();
                }
            }
    
            public object this[string name]
            {
                get
                {
                    return this.state[name];
                }
                set
                {
                    this.state[name] = value;
                }
            }
    
            #endregion
        }
    }
    
    0 讨论(0)
  • 2020-11-28 07:50

    Unless you use Typemock or Moles, you can't.

    In ASP.NET MVC you are not supposed to be using HttpContext.Current. Change your base class to use ControllerBase.ControllerContext - it has a HttpContext property that exposes the testable HttpContextBase class.

    Here's an example of how you can use Moq to set up a Mock HttpContextBase:

    var httpCtxStub = new Mock<HttpContextBase>();
    
    var controllerCtx = new ControllerContext();
    controllerCtx.HttpContext = httpCtxStub.Object;
    
    sut.ControllerContext = controllerCtx;
    
    // Exercise and verify the sut
    

    where sut represents the System Under Test (SUT), i.e. the Controller you wish to test.

    0 讨论(0)
提交回复
热议问题