asp.net-mvc - una - mvc submit button action
¿Cómo se burla de la Solicitud de Controlador en ASP.Net MVC? (7)
Aquí hay una solución de trabajo que usa RhinoMocks. Lo he basado en una solución de Moq que encontré en http://thegrayzone.co.uk/blog/2010/03/mocking-request-isajaxrequest/
public static void MakeAjaxRequest(this Controller controller)
{
MockRepository mocks = new MockRepository();
// Create mocks
var mockedhttpContext = mocks.DynamicMock<HttpContextBase>();
var mockedHttpRequest = mocks.DynamicMock<HttpRequestBase>();
// Set headers to pretend it''s an Ajax request
SetupResult.For(mockedHttpRequest.Headers)
.Return(new WebHeaderCollection() {
{"X-Requested-With", "XMLHttpRequest"}
});
// Tell the mocked context to return the mocked request
SetupResult.For(mockedhttpContext.Request).Return(mockedHttpRequest);
mocks.ReplayAll();
// Set controllerContext
controller.ControllerContext = new ControllerContext(mockedhttpContext, new RouteData(), controller);
}
Tengo un controlador en C # usando el marco ASP.Net MVC
public class HomeController:Controller{
public ActionResult Index()
{
if (Request.IsAjaxRequest())
{
//do some ajaxy stuff
}
return View("Index");
}
}
Recibí algunos consejos sobre burlas y esperaba probar el código con lo siguiente y RhinoMocks
var mocks = new MockRepository();
var mockedhttpContext = mocks.DynamicMock<HttpContextBase>();
var mockedHttpRequest = mocks.DynamicMock<HttpRequestBase>();
SetupResult.For(mockedhttpContext.Request).Return(mockedHttpRequest);
var controller = new HomeController();
controller.ControllerContext = new ControllerContext(mockedhttpContext, new RouteData(), controller);
var result = controller.Index() as ViewResult;
Assert.AreEqual("About", result.ViewName);
Sin embargo sigo recibiendo este error:
Exception System.ArgumentNullException: System.ArgumentNullException: el valor no puede ser nulo. Nombre del parámetro: solicitud en System.Web.Mvc.AjaxRequestExtensions.IsAjaxRequest (solicitud HttpRequestBase)
Dado que el objeto Request
en el controlador no tiene setter. Traté de que esta prueba funcionara correctamente utilizando el código recomendado de la respuesta a continuación.
Esto usó Moq en lugar de RhinoMocks, y al usar Moq uso lo siguiente para la misma prueba:
var request = new Mock<HttpRequestBase>();
// Not working - IsAjaxRequest() is static extension method and cannot be mocked
// request.Setup(x => x.IsAjaxRequest()).Returns(true /* or false */);
// use this
request.SetupGet(x => x.Headers["X-Requested-With"]).Returns("XMLHttpRequest");
var context = new Mock<HttpContextBase>();
context.SetupGet(x => x.Request).Returns(request.Object);
var controller = new HomeController(Repository, LoginInfoProvider);
controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
var result = controller.Index() as ViewResult;
Assert.AreEqual("About", result.ViewName);
pero recibe el siguiente error:
Exception System.ArgumentException: System.ArgumentException: configuración no válida en un miembro no invalidable: x => x.Headers ["X-Requested-With"] en Moq.Mock.ThrowIfCantOverride (Configuración de expresión, MethodInfo methodInfo)
Nuevamente, parece que no puedo configurar el encabezado de la solicitud. ¿Cómo configuro este valor en RhinoMocks o Moq?
Debes burlarte de HttpContextBase y ponerlo en tu propiedad ControllerContext, así:
controller.ControllerContext =
new ControllerContext(mockedHttpContext, new RouteData(), controller);
Es AjaxRequest es un método de extensión. Entonces puedes hacerlo de la siguiente manera usando Rhino:
protected HttpContextBase BuildHttpContextStub(bool isAjaxRequest)
{
var httpRequestBase = MockRepository.GenerateStub<HttpRequestBase>();
if (isAjaxRequest)
{
httpRequestBase.Stub(r => r["X-Requested-With"]).Return("XMLHttpRequest");
}
var httpContextBase = MockRepository.GenerateStub<HttpContextBase>();
httpContextBase.Stub(c => c.Request).Return(httpRequestBase);
return httpContextBase;
}
// Build controller
....
controller.ControllerContext = new ControllerContext(BuildHttpContextStub(true), new RouteData(), controller);
Para cualquiera que use NSubstitute, pude modificar las respuestas anteriores y hacer algo como esto ... (donde Details es el nombre del método de acción en el controlador)
var fakeRequest = Substitute.For<HttpRequestBase>();
var fakeContext = Substitute.For<HttpContextBase>();
fakeRequest.Headers.Returns(new WebHeaderCollection { {"X-Requested-With", "XMLHttpRequest"}});
fakeContext.Request.Returns(fakeRequest);
controller.ControllerContext = new ControllerContext(fakeContext, new RouteData(), controller);
var model = new EntityTypeMaintenanceModel();
var result = controller.Details(model) as PartialViewResult;
Assert.IsNotNull(result);
Assert.AreEqual("EntityType", result.ViewName);
Para hacer que IsAjaxRequest()
devuelva falso durante la prueba de unidad, necesita configurar los encabezados de solicitud y solicitar el valor de recopilación tanto en su método de prueba como a continuación:
_request.SetupGet(x => x.Headers).Returns(new System.Net.WebHeaderCollection { { "X-Requested-With", "NotAjaxRequest" } });
_request.SetupGet(x=>x["X-Requested-With"]).Returns("NotAjaxRequest");
El motivo para configurar ambos está oculto en la implementación de IsAjaxRequest () que se muestra a continuación:
public static bool IsAjaxRequest(this HttpRequestBase request)<br/>
{
if (request == null)
{
throw new ArgumentNullException("request");
}
return ((request["X-Requested-With"] == "XMLHttpRequest") || ((request.Headers != null) && (request.Headers["X-Requested-With"] == "XMLHttpRequest")));
}
Utiliza tanto la colección de solicitudes como el encabezado. Es por eso que debemos crear la configuración tanto para el encabezado como para la colección de solicitudes.
esto hará que la solicitud devuelva falso cuando no es una solicitud AJAX. para que sea verdadero, puede hacer lo siguiente:
_httpContext.SetupGet(x => x.Request["X-Requested-With"]).Returns("XMLHttpRequest");
Parece que estás buscando esto,
var requestMock = new Mock<HttpRequestBase>();
requestMock.SetupGet(rq => rq["Age"]).Returns("2001");
Uso en el controlador:
public ActionResult Index()
{
var age = Request["Age"]; //This will return 2001
}
Usando Moq :
var request = new Mock<HttpRequestBase>();
// Not working - IsAjaxRequest() is static extension method and cannot be mocked
// request.Setup(x => x.IsAjaxRequest()).Returns(true /* or false */);
// use this
request.SetupGet(x => x.Headers).Returns(
new System.Net.WebHeaderCollection {
{"X-Requested-With", "XMLHttpRequest"}
});
var context = new Mock<HttpContextBase>();
context.SetupGet(x => x.Request).Returns(request.Object);
var controller = new YourController();
controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
ACTUALIZADO:
Mock Request.Headers["X-Requested-With"]
o Request["X-Requested-With"]
lugar de Request.IsAjaxRequest()
.