我想对控制器进行单元测试,但是从HttpContext.Session
读取值时遇到问题。
我想从我的控制器中模拟这一段:HttpContext.Session.Get<int>(Foo)
使用Mock HttpContext for unit testing a .NET core MVC controller?和 How to mock Session Object in asp net core我能够得出以下解决方案:
我的测试:
public void GetFoos_AllGood_ReturnList()
{
//Arrange
Mock<ISession> sessionMock = new Mock<ISession>();
var fooSessionValue = new byte[0];
Web.Controllers.FooController fooController = new Web.Controllers.FooController();
fooController.ControllerContext.HttpContext = new DefaultHttpContext();
fooController.ControllerContext.HttpContext.Request.Headers["Foo"] = 0;
Mock<IServiceCollection> mock = new Mock<IServiceCollection>();
mock.Object.AddSession(); // Tried this, but failed
//Setup
sessionMock.Setup(_ => _.Set("Foo", It.IsAny<byte[]>())).Callback<string, byte[]>((k, v) => fooSessionValue = v);
sessionMock.Setup(_ => _.TryGetValue("Foo", out fooSessionValue)).Returns(true);
mockWebDataManager.Setup(b => b.GetFoos(It.IsAny<FooArgs>())).Returns(new FooResult() { Foos = new List<Foo>() });
//Act
var result = fooController.GetFoos() as JsonResult;
//Assert
Assert.NotNull(result);
Assert.Equal(200, result.StatusCode);
}
我的控制器:
internal virtual DataArgs CreateArgs()
{
return new FooArgs
{
HttpContext.Session.Get<int>(Foo) // I want to Mock this value
};
}
[HttpGet]
public IActionResult GetFoos()
{
FooArgs args = CreateArgs();
...
}
答案 0 :(得分:0)
如果有一天有人遇到相同的问题,那么您可以这样做:
public void GetFoos_AllGood_ReturnList()
{
//Arrange
Mock<ISession> sessionMock = new Mock<ISession>();
Web.Controllers.FooController fooController = new Web.Controllers.FooController();
fooController.ControllerContext.HttpContext = new DefaultHttpContext();
fooController.ControllerContext.HttpContext.Request.Headers["Foo"] = 0;
fooController.ControllerContext.HttpContext.Session = sessionMock.Object;
//Act
var result = fooController.GetFoos() as JsonResult;
//Assert
Assert.NotNull(result);
}
答案 1 :(得分:0)
感谢Hypernate的回答,但就我而言,我不得不在单元测试中处理GetInt32和SetInt32扩展方法。按照下面的source code是实现
public static void SetInt32(this ISession session, string key, int value)
{
var bytes = new byte[]
{
(byte)(value >> 24),
(byte)(0xFF & (value >> 16)),
(byte)(0xFF & (value >> 8)),
(byte)(0xFF & value)
};
session.Set(key, bytes);
}
public static int? GetInt32(this ISession session, string key)
{
var data = session.Get(key);
if (data == null || data.Length < 4)
{
return null;
}
return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
}
因此,按照我的回答,我必须做一些修改,如下所示。
Mock<ISession> sessionMock = new Mock<ISession>();
var key = "FY";
int fy = 2020;
var value = new byte[]
{
(byte)(fy >> 24),
(byte)(0xFF & (fy >> 16)),
(byte)(0xFF & (fy >> 8)),
(byte)(0xFF & fy)
};
sessionMock.Setup(_ => _.TryGetValue(key, out value)).Returns(true);
我在任何地方都找不到此消息,因此请在此处共享,以免对遇到相同问题的人有所帮助。