68 votes

Se Moquant De L'Asp.net mvc Contexte de Contrôleur

De sorte que le contrôleur de contexte dépend de certains asp.net des éléments internes. Ce sont quelques façons à proprement se moquer de ces pour les tests unitaires? On dirait que son très facile de se boucher les tests avec des tonnes de configuration lorsque j'ai seulement besoin de, par exemple, Demande.HttpMethod de retour de "GET".

J'ai vu quelques exemples/aides sur les filets, mais certains sont datés. Pensé que ce serait un bon endroit pour garder les plus récents et les plus grands.

Je suis l'aide de la dernière version de rhino se moque de

64voto

Haacked Points 31070

À l'aide de MoQ il ressemble à quelque chose comme ceci:

var request = new Mock<HttpRequestBase>();
request.Expect(r => r.HttpMethod).Returns("GET");
var mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Expect(c => c.Request).Returns(request.Object);
var controllerContext = new ControllerContext(mockHttpContext.Object
, new RouteData(), new Mock<ControllerBase>().Object);

Je pense que le Rhino se moque de la syntaxe est similaire.

21voto

Maksym Kozlenko Points 4557

Voici un exemple de test de l'unité de la classe à l'aide de MsTest et Moq se moque de qui HttpRequest et HttpResponse objets. (.NET 4.0, ASP.NET MVC 3.0 )

Action de contrôleur d'obtenir la valeur de la demande et définit l'en-tête http de la réponse des objets. Autres http contexte des objets de la maquette, de la même façon

[TestClass]
public class MyControllerTest
{
    protected Mock<HttpContextBase> HttpContextBaseMock;
    protected Mock<HttpRequestBase> HttpRequestMock;
    protected Mock<HttpResponseBase> HttpResponseMock;

    [TestInitialize]
    public void TestInitialize()
    {
        HttpContextBaseMock = new Mock<HttpContextBase>();
        HttpRequestMock = new Mock<HttpRequestBase>();
        HttpResponseMock = new Mock<HttpResponseBase>();
        HttpContextBaseMock.SetupGet(x => x.Request).Returns(HttpRequestMock.Object);
        HttpContextBaseMock.SetupGet(x => x.Response).Returns(HttpResponseMock.Object);
    }

    protected MyController SetupController()
    {
        var routes = new RouteCollection();
        var controller = new MyController();
        controller.ControllerContext = new ControllerContext(HttpContextBaseMock.Object, new RouteData(), controller);
        controller.Url = new UrlHelper(new RequestContext(HttpContextBaseMock.Object, new RouteData()), routes);
        return controller;
    }

    [TestMethod]
    public void IndexTest()
    {
        HttpRequestMock.Setup(x => x["x"]).Returns("1");
        HttpResponseMock.Setup(x => x.AddHeader("name", "value"));

        var controller = SetupController();
        var result = controller.Index();
        Assert.AreEqual("1", result.Content);

        HttpRequestMock.VerifyAll();
        HttpResponseMock.VerifyAll();
    }
}

public class MyController : Controller
{
    public ContentResult Index()
    {
        var x = Request["x"];
        Response.AddHeader("name", "value");
        return Content(x);
    }
}

19voto

thedeeno Points 12553

Voici un extrait de Jason lien. C'est la même que Phil méthode, mais utilise rhino.

Remarque: mockHttpContext.La demande est écrasé à retourner mockRequest avant mockRequest internals sont écrasé. Je crois que cette commande est nécessaire.

// create a fake web context
var mockHttpContext = MockRepository.GenerateMock<HttpContextBase>();
var mockRequest = MockRepository.GenerateMock<HttpRequestBase>();
mockHttpContext.Stub(x => x.Request).Return(mockRequest);

// tell the mock to return "GET" when HttpMethod is called
mockRequest.Stub(x => x.HttpMethod).Return("GET");            

var controller = new AccountController();

// assign the fake context
var context = new ControllerContext(mockHttpContext, 
                  new RouteData(), 
                  controller);
controller.ControllerContext = context;

// act
...

10voto

Gabe Moothart Points 12400

La procédure semble avoir été légèrement modifié dans MVC2 (je suis en utilisant RC1). Phil Haack la solution ne fonctionne pas pour moi, si une action nécessite une méthode spécifique ([HttpPost], [HttpGet]). La spéléologie autour de Réflecteur, il semble que la méthode de vérification de ces attributs a changé. MVC vérifie request.Headers, request.Form, et request.QueryString d'un X-HTTP-Method-Override de la valeur.

Si vous ajoutez se moque de ces propriétés, il fonctionne:

var request = new Mock<HttpRequestBase>();
request.Setup(r => r.HttpMethod).Returns("POST");
request.Setup(r => r.Headers).Returns(new NameValueCollection());
request.Setup(r => r.Form).Returns(new NameValueCollection());
request.Setup(r => r.QueryString).Returns(new NameValueCollection());

var mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Expect(c => c.Request).Returns(request.Object);
var controllerContext = new ControllerContext(mockHttpContext.Object, new RouteData(), new Mock<ControllerBase>().Object);

7voto

RoyOsherove Points 2302

Ou vous pouvez le faire avec Typemock Isolateur avec pas besoin de nous envoyer un faux contrôleur à tous:

Isolate.WhenCalled(()=>HttpContext.Request.HttpMethod).WillReturn("Get");

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