如何在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);
答案 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;
}