如何使用 FakeItEasy 模拟 Request.IsAjaxRequest() 为真?
How to mock Request.IsAjaxRequest() to true using FakeItEasy?
以下是我要为其编写单元测试的代码片段:
[HttpGet]
public ActionResult Edit(string id)
{
if (Request.IsAjaxRequest())
{
EditModel model = new EditModel();
.....
}
return View();
}
我想为此操作编写单元测试,我可以在其中将 Request.IsAjaxRequest()
的结果伪造为 true,以便我可以为该操作的其余代码编写测试。
我试过关注,但没用。 _request.Headers
始终为空,而 Request.IsAjaxRequest()
始终返回 false:
[Fact]
public void Get_Edit_AjaxRequest_ExpectedActionCalled()
{
HttpRequestBase _request = A.Fake<HttpRequestBase>();
_request.Headers.Add("X-Requested-With", "XMLHttpRequest");
_controller.ControllerContext = A.Fake<ControllerContext>();
_controller.ControllerContext.HttpContext = _request;
A.CallTo(() => _controller.Request).Returns(_request);
var result = _controller.Edit(1) as RedirectToRouteResult;
}
我总是认为 Request.IsAjaxRequest()
是错误的。非常感谢对此的任何帮助。谢谢
我设法解决了编译错误并使用了 FakeItEasy Succinctly 第 10 章中的一些信息,这些信息都是关于 ASP.NET MVC 的。
一般来说,ASP.NET MVC 类 的设计并不是为了让它们容易被伪造,但我有一个测试设置导致 IsAjaxRequest
到 return 真的。两个主要障碍是让控制器使用请求 object 并确保请求 object 是 return 我们想要的 headers。
第一部分并不难,但第二部分要求我们让请求 object 使用具体的 NameValueCollection
。它默认提供的伪造的属性没有用,因为正确的属性不是虚拟的。幸运的是,使用真正的 NameValueCollection 就可以了。
试试这个:
[Fact]
public void Get_Edit_AjaxRequest_ExpectedActionCalled_Blair()
{
HttpRequestBase _request = A.Fake<HttpRequestBase>();
// NameValueCollection is effectively unfakeable due to non-virtual properties,
// but a real one works just fine, so make sure the headers use one of those.
A.CallTo(() => _request.Headers).Returns(new NameValueCollection());
_request.Headers["X-Requested-With"] = "XMLHttpRequest";
var httpContext = A.Fake<HttpContextBase>();
A.CallTo(() => httpContext.Request).Returns(_request);
_controller.ControllerContext = new ControllerContext(
new RequestContext(httpContext, new RouteData()),
_controller);
var result = _controller.Edit(1) as RedirectToRouteResult;
}
请注意,在 MVC 框架中会有很多这样的陷阱,继续伪造它们可能会继续令人沮丧。您可能会发现一种更可持续的方法是将尽可能多的逻辑提取到不依赖 MVC 框架的普通旧可测试业务中。
以下是我要为其编写单元测试的代码片段:
[HttpGet]
public ActionResult Edit(string id)
{
if (Request.IsAjaxRequest())
{
EditModel model = new EditModel();
.....
}
return View();
}
我想为此操作编写单元测试,我可以在其中将 Request.IsAjaxRequest()
的结果伪造为 true,以便我可以为该操作的其余代码编写测试。
我试过关注,但没用。 _request.Headers
始终为空,而 Request.IsAjaxRequest()
始终返回 false:
[Fact]
public void Get_Edit_AjaxRequest_ExpectedActionCalled()
{
HttpRequestBase _request = A.Fake<HttpRequestBase>();
_request.Headers.Add("X-Requested-With", "XMLHttpRequest");
_controller.ControllerContext = A.Fake<ControllerContext>();
_controller.ControllerContext.HttpContext = _request;
A.CallTo(() => _controller.Request).Returns(_request);
var result = _controller.Edit(1) as RedirectToRouteResult;
}
我总是认为 Request.IsAjaxRequest()
是错误的。非常感谢对此的任何帮助。谢谢
我设法解决了编译错误并使用了 FakeItEasy Succinctly 第 10 章中的一些信息,这些信息都是关于 ASP.NET MVC 的。
一般来说,ASP.NET MVC 类 的设计并不是为了让它们容易被伪造,但我有一个测试设置导致 IsAjaxRequest
到 return 真的。两个主要障碍是让控制器使用请求 object 并确保请求 object 是 return 我们想要的 headers。
第一部分并不难,但第二部分要求我们让请求 object 使用具体的 NameValueCollection
。它默认提供的伪造的属性没有用,因为正确的属性不是虚拟的。幸运的是,使用真正的 NameValueCollection 就可以了。
试试这个:
[Fact]
public void Get_Edit_AjaxRequest_ExpectedActionCalled_Blair()
{
HttpRequestBase _request = A.Fake<HttpRequestBase>();
// NameValueCollection is effectively unfakeable due to non-virtual properties,
// but a real one works just fine, so make sure the headers use one of those.
A.CallTo(() => _request.Headers).Returns(new NameValueCollection());
_request.Headers["X-Requested-With"] = "XMLHttpRequest";
var httpContext = A.Fake<HttpContextBase>();
A.CallTo(() => httpContext.Request).Returns(_request);
_controller.ControllerContext = new ControllerContext(
new RequestContext(httpContext, new RouteData()),
_controller);
var result = _controller.Edit(1) as RedirectToRouteResult;
}
请注意,在 MVC 框架中会有很多这样的陷阱,继续伪造它们可能会继续令人沮丧。您可能会发现一种更可持续的方法是将尽可能多的逻辑提取到不依赖 MVC 框架的普通旧可测试业务中。