我有一个基于某些内部逻辑的函数,在会话变量(Redirect_To)中存储重定向字符串。我正在尝试编写一个单元测试,一旦调用的操作完成,它将检查此会话变量的值。
我正在使用Moq来模拟我的一些属性和功能。但是,每当我使用Moq设置Session变量(Redirect_To)时,它必须将其设置为只读,因为我不能再为其分配值,这导致我的单元测试失败。
这是我的单元测试:
public async Task Index_ClientTypeIsRPI_ExpectCorrectRedirect()
{
var sessionDict = new Dictionary<string, string>
{
{"CID", "124" },
{"UserName", "AK92630" },
{"REDIRECT_TO", "www.google.com" }
};
var controllerContext = HttpContextManager.ReturnMockControllerContextWithSessionVars(sessionDict);
var mockIdentity = new Mock<IIdentity>();
mockIdentity.Setup(x => x.Name).Returns("TestName");
controllerContext.Setup(x => x.HttpContext.User.Identity).Returns(mockIdentity.Object);
controllerContext.Setup(x => x.HttpContext.User.IsInRole(UserLevel.Subrep.GetDescription())).Returns(true);
controllerContext.Setup(x => x.HttpContext.Request.Browser.Browser).Returns("InternetExplorer");
_controller.ControllerContext = controllerContext.Object;
_iMockManifestManager.Setup(x => x.ReturnSingleMainDataRecordViaTransNoCIDAndUserNameAsync(It.IsAny<string>, It.IsAny<string>, It.IsAny<string>)).ReturnsAsync(New MainData());
var transNo = "Asdf";
await _controller.Index(transNo, true, "sd", "dg");
Assert.AreEqual("www.facebook.com", _controller.HttpContext.Session["REDIRECT_TO"]);
}
ReturnMockControllerContextWithSessionVars(设置会话变量的函数)
internal static Mock<ControllerContext> ReturnMockControllerContextWithSessionVars(Dictionary<string, object> sessionKeysAndValues):
{
var fakeHttpContext = HttpContextManager.CreateLocalAuthenticatedUserWithMockHttpContext();
var controllerContext = new Mock<ControllerContext>;
controllerContext.Setup(x => x.HttpContext).Returns(fakeHttpContext.Object);
foreach (var item in sessionKeysAndValues)
{
controllerContext.Setup(x => x.HttpContext.Session[item.Key]).Returns(item.Value);
}
return controllerContext;
}
动作:
public async Task Index(string transNo, bool? isRechase, string clientID, string clientType)
{
switch (clientType.ToUpper())
{
case "RPI":
Session["REDIRECT_TO"] = "www.reddit.com";
break;
case "LM":
Session["REDIRECT_TO"] = "www.bbc.co.uk";
default:
Session["REDIRECT_TO"] = "www.stackoverflow.com";
break;
}
//Do async stuff
return null;
}
有人知道如何更改我的代码,所以当我设置Session["Redirect_To"]
时,它仍然是可读/写的吗?
另外,我已经从VB.NET转换了这个,但是我能熟练使用这两种语言,所以如果我犯了任何语法错误,那就是免费编写它。如果是这样,请告诉我。
由于
答案 0 :(得分:1)
创建一个用于会话的存根,因为moq将难以设置用于保存索引属性中的值的集合。其他依赖项应该按照预期使用moq。
class HttpSessionStateMock : HttpSessionStateBase {
private readonly IDictionary<string, object> objects = new Dictionary<string, object>();
public HttpSessionStateMock(IDictionary<string, object> objects = null) {
this.objects = objects ?? new Dictionary<string, object>();
}
public override object this[string name] {
get { return (objects.ContainsKey(name)) ? objects[name] : null; }
set { objects[name] = value; }
}
}
使用原始问题库中的示例方法"RPI"
作为clientType
以下测试已完成并按预期传递。
[TestMethod]
public async Task Index_ClientTypeIsRPI_ExpectCorrectRedirect() {
//Arrange
var mock = new MockRepository(MockBehavior.Loose) {
DefaultValue = DefaultValue.Mock,
};
var session = new HttpSessionStateMock();//<-- session stub
var controllerContext = mock.Create<ControllerContext>();
controllerContext.Setup(_ => _.HttpContext.Session).Returns(session);
var _controller = new MyController() {
ControllerContext = controllerContext.Object
};
var transNo = "Asdf";
var clientID = "123";
var clientType = "RPI";
var sessionKey = "REDIRECT_TO";
var expected = "www.reddit.com";
//Act
await _controller.Index(transNo, true, clientID, clientType);
var actual = _controller.HttpContext.Session[sessionKey].ToString();
//Assert
Assert.AreEqual(expected, actual);
}