代码之家  ›  专栏  ›  技术社区  ›  amurra

带有httpcontext的asp.net mvc单元测试控制器

  •  30
  • amurra  · 技术社区  · 14 年前

    我正试图为我的一个控制器编写一个单元测试,以验证是否正确返回了视图,但是这个控制器有一个访问httpcontext.current.session的basecontroller。每次我创建控制器的新实例时,都会调用BaseController构造函数,测试失败,HttpContext.current.session上出现空指针异常。代码如下:

    public class BaseController : Controller
    {       
        protected BaseController()
        {
           ViewData["UserID"] = HttpContext.Current.Session["UserID"];   
        }
    }
    
    public class IndexController : BaseController
    {
        public ActionResult Index()
        {
            return View("Index.aspx");
        }
    }
    
        [TestMethod]
        public void Retrieve_IndexTest()
        {
            // Arrange
            const string expectedViewName = "Index";
    
            IndexController controller = new IndexController();
    
            // 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);
        }
    

    关于如何模拟(使用moq)在基本控制器中访问的会话以便在子控制器中运行测试的任何想法?

    5 回复  |  直到 11 年前
        1
  •  5
  •   Graviton    14 年前

    如果你正在使用 Typemock ,您可以执行以下操作:

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

    测试代码将如下所示:

    [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);
    }
    
        2
  •  64
  •   Community datashaman    7 年前

    除非你用typemock或moles, you can't .

    在asp.net mvc中,您不应该使用httpcontext.current。将基类更改为使用 ControllerBase.ControllerContext -它有一个 HttpContext 公开可测试内容的属性 HttpContextBase 班级。

    下面是一个如何使用moq设置模拟httpcontextbase的示例:

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

    哪里 sut 表示要测试的系统(SUT),即要测试的控制器。

        3
  •  3
  •   pdr    14 年前

    你应该用一个 ActionFilter 而不是这类的基类

    [UserIdBind]
    public class IndexController : Controller
    {
        public ActionResult Index()
        {
            return View("Index.aspx");
        }
    }
    
        4
  •  3
  •   m1k4    14 年前

    片段:

    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;
    

    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
        }
    }
    
        5
  •  1
  •   Nate CSS Guy    14 年前

    我想看看这里列出的asp.net-mvc书籍——最后,有一个关于模拟framewors的好部分-- http://www.hanselman.com/blog/FreeASPNETMVCEBookNerdDinnercomWalkthrough.aspx