我无法对包含HttpContext.Current.Request.LogonUserIdentity.Name
的功能之一进行单元测试
我得到的错误是因为LogonUserIdentity
为空。
我在单元测试中添加了此值,以便为HttpContext.Current
设置一个值,因为该值也为空:
HttpContext.Current = new HttpContext(
new HttpRequest("", "http://localhost:8609", ""),
new HttpResponse(new StringWriter())
);
如何为
LogonUserIdentity
分配值,以便测试功能?
答案 0 :(得分:3)
这预示着更大的问题。
LogonUserIdentity属性将WindowsIdentity对象的属性和方法公开给当前连接到Microsoft Internet信息服务(IIS)的用户。 LogonUserIdentity公开的WindowsIdentity类的实例跟踪IIS请求令牌,并为在ASP.NET内部处理的当前HTTP请求提供对此令牌的轻松访问。 会自动创建WindowsIdentity类的实例,因此无需构造即可获取其方法和属性。
Source (强调我的)
如何为
LogonUserIdentity
分配值,以便测试功能?
不能。由于IIS不可用,因此不在单元测试中。
避免将您的代码与无法控制的无法测试的代码紧密结合在一起,例如HttpContext
和System.Web
名称空间的大部分。
相反,将它们封装在您可以控制并可以模拟的抽象后面。
答案 1 :(得分:1)
并不是最好的模拟游戏,但有时您会被困住。
在此解决方案中,您必须处理控制器和/或控制器上的本地登录用户(johndoe) 在您的数据库中。
但是可以。
var mockRequest = new HttpRequest("", "http://tempuri.org", "");
HttpContext.Current = new HttpContext(
mockRequest,
new HttpResponse(new StringWriter())
);
mockRequest.GetType().InvokeMember(
"_logonUserIdentity",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.SetField | System.Reflection.BindingFlags.Instance,
System.Type.DefaultBinder,
mockRequest,
new object[] { WindowsIdentity.GetCurrent() }
);
答案 2 :(得分:0)
您可以如此处所示模拟上下文
var requestMock = new Mock<HttpRequestBase>();
var contextMock = new Mock<HttpContextBase>();
var mockIIdentity = new Mock<IIdentity>();
mockIIdentity.SetupGet(x => x.Name).Returns("MyName");
WindowsIdentity windowsIdentity = mockIIdentity.Object as WindowsIdentity;
requestMock.Setup(x => x.LogonUserIdentity).Returns(windowsIdentity);
contextMock.Setup(x => x.Request).Returns(requestMock.Object);
yourControllerInstance.ControllerContext new ControllerContext(contextMock.Object, new RouteData(), yourControllerInstance)
我还有一个编写的测试帮助程序,您可以在Github中找到它并尝试使用它,您可以对其进行修改以合并上述设置https://github.com/danielhunex/TestHelper
答案 3 :(得分:0)
您可以使用(System.Web.Fakes)这样模拟它:
ShimHttpRequest.AllInstances.LogonUserIdentityGet =(a)=> {return WindowsIdentity.GetCurrent(); };
答案 4 :(得分:0)
我花了很多时间尝试模拟HttpContext或HttpContextBase,然后尝试使用伪造的WindowsIdentity类或HttpRequest.LogonUserIdentity属性进行填充。 什么都行不通-不需要完全模拟的HttpContext,因为您希望看到真实的响应,而不是返回模拟设置。 只是不会为WindowsIdentity类(“由于内部限制”)和LogonUserIdentity属性(在伪造消息中没有给出原因,只是不存在)而生成垫片。
此处介绍了如何通过请求和响应获取可测试的HttpContext的最佳方法: http://jonlanceley.blogspot.com/2015/08/unit-testing-part-2-faking-httpcontext.html
我能够在伪造的请求包装程序中覆盖LogonUserIdentity属性,并在其中设置所需的内容。