Unit-testing an action which calls session object

后端 未结 1 766
囚心锁ツ
囚心锁ツ 2021-01-25 01:03

How can I unit test a method which uses a session object inside of its body?

Let us say I have the following action:

[HttpPost]
public JsonResult GetSear         


        
1条回答
  •  星月不相逢
    2021-01-25 01:48

    I've solved similar issues (use of static data accessors that aren't mock friendly - in particular, HttpContext.Current) by wrapping the access in another object, and accessing it through an interface. You could do something like:

    pubic interface ISessionData
    {
        ExtraFieldsLinker CurrentExtraFieldsLinker { get; set; }
    }
    
    public class SessionDataImpl : ISessionData
    {
        ExtraFieldsLinker CurrentExtraFieldsLinker
        {
            // Note: this code is somewhat bogus,
            // since I think these are methods of your class.
            // But it illustrates the point.  You'd put all the access here
            get { return (ExtraFieldsLinker)GetSessionObject(EXTRA_FIELDS_LINKER); }
            set { SetSessionObject(EXTRA_FIELDS_LINKER, value); }
        }
    }
    
    public class ClassThatContainsYourAction
    {
        static ClassThatContainsYourAction()
        {
            SessionData = new SessionDataImpl();
        }
    
        public static ISessionData SessionData { get; private set; }
    
        // Making this access very ugly so you don't do it by accident
        public void SetSessionDataForUnitTests(ISessionData sessionData)
        {
            SessionData = sessionData;
        }
    
        [HttpPost]
        public JsonResult GetSearchResultGrid(JqGridParams gridParams,
            Guid campaignId, string queryItemsString)
        {
            var queryItems = // ...
            IPageData pageData = // ...
    
            // Access your shared state only through SessionData
            var extraFieldLinker = SessionData.CurrentExtraFieldsLinker;
    
            // ...
        }
    }
    

    Then your unit test can set the ISessionData instance to a mock object before calling GetSearchResultGrid.

    Ideally you'd use a Dependency Injection library at some point, and get rid of the static constructor.

    If you can figure out a way to make your ISessionData an instanced object instead of static, even better. Mock object frameworks tend to like to create a new mock type for every test case, and having mocks lying around from previous tests is kind of gross. I believe session state is going to be global to your session anyway, so you might not have to do anything tricky to make a non-static object work.

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