170 votes

Comment simuler la requête sur le contrôleur dans ASP.Net MVC?

J'ai un contrôleur en C# à l'aide de la ASP.Net framework MVC

public class HomeController:Controller{
  public ActionResult Index()
    {
      if (Request.IsAjaxRequest())
        { 
          //do some ajaxy stuff
        }
      return View("Index");
    }
}

J'ai quelques conseils sur la moquerie et a été en espérant pour tester le code avec la commande suivante et 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);

Cependant, je reçois cette erreur:

Exception Système.ArgumentNullException: Système.ArgumentNullException : Valeur ne peut pas être null. Nom du paramètre: demande à Système.Web.Mvc.AjaxRequestExtensions.IsAjaxRequest(HttpRequestBase demande)

Depuis l' Request objet sur le contrôleur n'a pas de setter. J'ai essayé de faire ce test fonctionne correctement en utilisant recommandé de code à partir d'une réponse ci-dessous.

Ce Moq au lieu de RhinoMocks, et en utilisant Moq j'utilise la suite pour le même test:

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);

mais obtiens l'erreur suivante:

Système D'Exception.ArgumentException: Système.ArgumentException : Invalides le programme d'installation sur un non-substituables membre: x => x.Les en-têtes["X-requested-with"] Moq.Se moquer.ThrowIfCantOverride(Expression le programme d'installation, MethodInfo methodInfo)

Encore une fois, il semble que je ne peux pas définir l'entête de la requête. Comment définir cette valeur, dans RhinoMocks ou Moq?

208voto

eu-ge-ne Points 17847

En utilisant 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);
 

ACTUALISÉ:

Faux Request.Headers["X-Requested-With"] ou Request["X-Requested-With"] au lieu de Request.IsAjaxRequest() .

17voto

sjmarsh Points 66

Pour toute personne utilisant NSubstitute, j'ai pu modifier les réponses ci-dessus et faire quelque chose comme ça (où Details est le nom de la méthode Action sur le contrôleur)

  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);
 

13voto

Phil Hale Points 1534

Voici une solution de travail utilisant RhinoMocks. Je l'ai basé sur une solution Moq que j'ai trouvée à 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);
}
 

5voto

Jeroen Bernsen Points 51

AjaxRequest est une méthode d’extension. Si vous pouvez le faire comme suit à l’aide de Rhino :

3voto

Michał Chaniewski Points 2125

Il faut se moquer HttpContextBase et mettez-la dans votre propriété ControllerContext, comme ça :

Ici vous pouvez voir comment se moquer de la collection Form, votre scénario sera similaire : se moquer de l’objet HttpRequest dans ASP.NET MVC

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X