我正在研究一个ASP.NET MVC应用程序,并且正在尝试针对控制器操作编写一些单元测试,其中一些操作处理HttpContext上的属性,例如Session,Request.Cookies,Response.Cookies等。我在弄清楚如何“安排,行动,断言”时遇到了一些麻烦......我可以看到安排和断言......但是我无法弄清楚如何对一个模拟的HttpContextBase的属性进行“行动”其属性只有吸气剂。我无法在我的控制器操作中设置我的模拟上下文中的任何内容...所以它似乎没有用。我很嘲笑,所以我确定有一些我缺少的东西,但我认为我应该能够创建一个模拟对象,我可以在测试控制器操作的上下文中使用实际上可以设置属性值,然后断言它们仍然是我设置它们的东西,或类似的东西。我错过了什么?
public static HttpContextBase GetMockHttpContext()
{
var requestCookies = new Mock<HttpCookieCollection>();
var request = new Mock<HttpRequestBase>();
request.Setup(r => r.Cookies).Returns(requestCookies.Object);
request.Setup(r => r.Url).Returns(new Uri("http://example.org"));
var responseCookies = new Mock<HttpCookieCollection>();
var response = new Mock<HttpResponseBase>();
response.Setup(r => r.Cookies).Returns(responseCookies.Object);
var context = new Mock<HttpContextBase>();
context.Setup(ctx => ctx.Request).Returns(request.Object);
context.Setup(ctx => ctx.Response).Returns(response.Object);
context.Setup(ctx => ctx.Session).Returns(new Mock<HttpSessionStateBase>().Object);
context.Setup(ctx => ctx.Server).Returns(new Mock<HttpServerUtilityBase>().Object);
context.Setup(ctx => ctx.User).Returns(GetMockMembershipUser());
context.Setup(ctx => ctx.User.Identity).Returns(context.Object.User.Identity);
context.Setup(ctx => ctx.Response.Output).Returns(new StringWriter());
return context.Object;
}
答案 0 :(得分:4)
不确定是否有人有兴趣,但我已将Moq FakeHttpContext翻译为使用Rhino Mocks(我选择的武器)的一个。
public static HttpContextBase FakeHttpContext()
{
var httpContext = MockRepository.GenerateMock<HttpContextBase>();
var request = MockRepository.GenerateMock<HttpRequestBase>();
var response = MockRepository.GenerateMock<HttpResponseBase>();
var session = MockRepository.GenerateMock<HttpSessionStateBase>();
var server = MockRepository.GenerateMock<HttpServerUtilityBase>();
var cookies = new HttpCookieCollection();
response.Stub(r => r.Cookies).Return(cookies);
request.Stub(r => r.Cookies).Return(cookies);
request.Stub(r => r.Url).Return(new Uri("http://test.com"));
httpContext.Stub(x => x.Server).Return(server);
httpContext.Stub(x => x.Session).Return(session);
httpContext.Stub(x => x.Request).Return(request);
httpContext.Stub(x => x.Response).Return(response);
var writer = new StringWriter();
var wr = new SimpleWorkerRequest("", "", "", "", writer);
System.Web.HttpContext.Current = new System.Web.HttpContext(wr);
return httpContext;
}
用于
的单元测试_httpContext = FakeHttpContext();
var cookieManager = new CookieManager(_httpContext);
string username = cookieManager.GetUsername();
_httpContext.AssertWasCalled(hc => { var dummy = hc.Request; });
答案 1 :(得分:2)
我不完全肯定你为什么不能在Mocks上设置属性,但是如果你发布测试的完整代码,我很乐意和你一起完成它。在我的头顶,我会建议两件事:
Setup()和SetupProperty()之间存在差异。如果你想跟踪属性的值,而不是只从它们获取一次值,那么SetupProperty()可能就是你所追求的。
或者尝试在需要设置属性的任何模拟上调用SetupAllProperties()。
查看Moq quickstart以获取一些示例。