如何在ASP.net核心单元测试项目中模拟会话变量?

时间:2017-02-16 09:26:56

标签: asp.net unit-testing

如何在ASP.net核心单元测试项目中模拟会话变量?

1)我创建了一个会话的模拟对象。

模拟mockHttpContext = new Mock(); 模拟mockHttpContext = new Mock();模拟mockSession = new Mock()。As();

2)设置GetString()方法

mockSession.Setup(s => s.GetString(" ModuleId"))。返回(" 1");

3)创建了controllerContext并分配了mockhttpContext对象

controller.ControllerContext.HttpContext = mockHttpContext.Object;

4)尝试从控制器读取。

HttpContext.Session.GetString("的moduleId&#34)

然后我得到" ModuleId"的空值。请帮我模拟会话GetString()方法

示例:

        //Arrange
        //Note: Mock session 
        Mock<HttpContext> mockHttpContext = new Mock<HttpContext>();
        Mock<ITestSession> mockSession = new Mock<ISession>().As<ITestSession>();
        //Cast list to IEnumerable
        IEnumerable<string> sessionKeys = new string[] { };
        //Convert to list.
        List<string> listSessionKeys = sessionKeys.ToList();
        listSessionKeys.Add("ModuleId");
        sessionKeys = listSessionKeys;
        mockSession.Setup(s => s.Keys).Returns(sessionKeys);
        mockSession.Setup(s => s.Id).Returns("89eca97a-872a-4ba2-06fe-ba715c3f32be");
        mockSession.Setup(s => s.IsAvailable).Returns(true);
        mockHttpContext.Setup(s => s.Session).Returns(mockSession.Object);
     mockSession.Setup(s => s.GetString("ModuleId")).Returns("1");         

        //Mock TempData
        var tempDataMock = new Mock<ITempDataDictionary>();
        //tempDataMock.Setup(s => s.Peek("ModuleId")).Returns("1");

        //Mock service
        Mock<ITempServices> mockITempServices= new Mock<ITempServices>();
        mockITempServices.Setup(m => m.PostWebApiData(url)).Returns(Task.FromResult(response));

        //Mock Management class method
        Mock<ITestManagement> mockITestManagement = new Mock<ITestManagement>();
        mockITestManagement .Setup(s => s.SetFollowUnfollow(url)).Returns(Task.FromResult(response));

        //Call Controller method
        TestController controller = new TestController (mockITestManagement .Object, appSettings);
        controller.ControllerContext.HttpContext = mockHttpContext.Object;            
        controller.TempData = tempDataMock.Object;

        //Act
        string response = await controller.Follow("true");

        // Assert
        Assert.NotNull(response);
        Assert.IsType<string>(response);

5 个答案:

答案 0 :(得分:2)

首先创建类命名为mockHttpSession并从ISession继承。

公共类MockHttpSession:ISession     {         字典sessionStorage = new Dictionary();

    public object this[string name]
    {
        get { return sessionStorage[name]; }
        set { sessionStorage[name] = value; }
    }

    string ISession.Id
    {
        get
        {
            throw new NotImplementedException();
        }
    }

    bool ISession.IsAvailable
    {
        get
        {
            throw new NotImplementedException();
        }
    }

    IEnumerable<string> ISession.Keys
    {
        get { return sessionStorage.Keys; }
    }

    void ISession.Clear()
    {
        sessionStorage.Clear();
    }

    Task ISession.CommitAsync()
    {
        throw new NotImplementedException();
    }

    Task ISession.LoadAsync()
    {
        throw new NotImplementedException();
    }

    void ISession.Remove(string key)
    {
        sessionStorage.Remove(key);
    }

    void ISession.Set(string key, byte[] value)
    {
        sessionStorage[key] = value;
    }

    bool ISession.TryGetValue(string key, out byte[] value)
    {
        if (sessionStorage[key] != null)
        {
            value = Encoding.ASCII.GetBytes(sessionStorage[key].ToString());
            return true;
        }
        else
        {
            value = null;
            return false;
        }
    }        
**}**

然后在实际控制器中使用此会话:

     Mock<HttpContext> mockHttpContext = new Mock<HttpContext>();
        MockHttpSession mockSession = new MockHttpSession();           
        mockSession["Key"] = Value;
        mockHttpContext.Setup(s => s.Session).Returns(mockSession);
        Controller controller=new Controller();
        controller.ControllerContext.HttpContext = mockHttpContext.Object;

答案 1 :(得分:1)

我将Pankaj Dhote的课程用于模拟ISession。我必须从中更改一种方法:

bool ISession.TryGetValue(string key, out byte[] value)
{
    if (sessionStorage[key] != null)
    {
        value = Encoding.ASCII.GetBytes(sessionStorage[key].ToString());
        return true;
    }
    else
    {
        value = null;
        return false;
    }
}  

到下面的代码。否则,对sessionStorage [key] .ToString()的引用将返回类型的名称,而不是字典中的值。

    bool ISession.TryGetValue(string key, out byte[] value)
    {
        if (sessionStorage[key] != null)
        {
            value = (byte[])sessionStorage[key]; //Encoding.UTF8.GetBytes(sessionStorage[key].ToString())
            return true;
        }
        else
        {
            value = null;
            return false;
        }
    }

答案 2 :(得分:0)

我最近遇到了这个问题,唯一的方法是模拟GetString方法包装的函数,即TryGetValue。

byte[] dummy = System.Text.Encoding.UTF8.GetBytes(Guid.NewGuid().ToString());
_mockSession.Setup(x => x.TryGetValue(It.IsAny<string>(),out dummy)).Returns(true).Verifiable();

所以你不需要模拟对GetString方法的调用,你只需要模拟在幕后调用的方法。

答案 3 :(得分:0)

Pankaj Dhote给出的解决方案正在发挥作用。这是ASP.NET CORE 2 MVC完整的无错代码:

public class MockHttpSession : ISession
{
    Dictionary<string, object> sessionStorage = new Dictionary<string, object>();
    public object this[string name]
    {
        get { return sessionStorage[name]; }
        set { sessionStorage[name] = value; }
    }

    string ISession.Id
    {
        get
        {
            throw new NotImplementedException();
        }
    }
    bool ISession.IsAvailable
    {
        get
        {
            throw new NotImplementedException();
        }
    }
    IEnumerable<string> ISession.Keys
    {
        get { return sessionStorage.Keys; }
    }
    void ISession.Clear()
    {
        sessionStorage.Clear();
    }
    Task ISession.CommitAsync(CancellationToken cancellationToken = default(CancellationToken))
    {
        throw new NotImplementedException();
    }

    Task ISession.LoadAsync(CancellationToken cancellationToken = default(CancellationToken))
    {
        throw new NotImplementedException();
    }

    void ISession.Remove(string key)
    {
        sessionStorage.Remove(key);
    }

    void ISession.Set(string key, byte[] value)
    {
        sessionStorage[key] = value;
    }

    bool ISession.TryGetValue(string key, out byte[] value)
    {
        if (sessionStorage[key] != null)
        {
            value = Encoding.ASCII.GetBytes(sessionStorage[key].ToString());
            return true;
        }
        else
        {
            value = null;
            return false;
        }
    }
}

然后在实际控制器中使用此会话:

    Mock<HttpContext> mockHttpContext = new Mock<HttpContext>();
    MockHttpSession mockSession = new MockHttpSession();           
    mockSession["Key"] = Value;
    mockHttpContext.Setup(s => s.Session).Returns(mockSession);
    Controller controller=new Controller();
    controller.ControllerContext.HttpContext = mockHttpContext.Object;

答案 4 :(得分:0)

起初,我创建了ISession的实现:

public class MockHttpSession : ISession
{
    readonly Dictionary<string, object> _sessionStorage = new Dictionary<string, object>();
    string ISession.Id => throw new NotImplementedException();
    bool ISession.IsAvailable => throw new NotImplementedException();
    IEnumerable<string> ISession.Keys => _sessionStorage.Keys;
    void ISession.Clear()
    {
        _sessionStorage.Clear();
    }
    Task ISession.CommitAsync(CancellationToken cancellationToken)
    {
        throw new NotImplementedException();
    }
    Task ISession.LoadAsync(CancellationToken cancellationToken)
    {
        throw new NotImplementedException();
    }
    void ISession.Remove(string key)
    {
        _sessionStorage.Remove(key);
    }
    void ISession.Set(string key, byte[] value)
    {
        _sessionStorage[key] = Encoding.UTF8.GetString(value);
    }
    bool ISession.TryGetValue(string key, out byte[] value)
    {
        if (_sessionStorage[key] != null)
        {
            value = Encoding.ASCII.GetBytes(_sessionStorage[key].ToString());
            return true;
        }
        value = null;
        return false;
    }
}

其次是在控制器定义期间实现的:

private HomeController CreateHomeController()
        {
            var controller = new HomeController(
                mockLogger.Object,
                mockPollRepository.Object,
                mockUserRepository.Object)
            {
                ControllerContext = new ControllerContext
                {
                    HttpContext = new DefaultHttpContext() {Session = new MockHttpSession()}
                }
            };
            return controller;
        }