109 votes

Comment simuler le HttpContext dans ASP.NET MVC en utilisant Moq ?

[TestMethod]
public void Home_Message_Display_Unknown_User_when_coockie_does_not_exist()
{
    var context = new Mock<HttpContextBase>();
    var request = new Mock<HttpRequestBase>();
    context
        .Setup(c => c.Request)
        .Returns(request.Object);
    HomeController controller = new HomeController();

    controller.HttpContext = context; //Here I am getting an error (read only).
    ...
 }

Mon contrôleur de base a une surcharge de l'Initialize qui obtient ce requestContext. J'essaie de le transmettre mais il y a quelque chose que je ne fais pas correctement.

protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
    base.Initialize(requestContext);
}

Où puis-je obtenir plus d'informations sur l'imitation de mon RequestContext et HttpContext à l'aide de Moq ? J'essaie de simuler les cookies et le contexte général.

64voto

tvanfosson Points 268301

HttpContext est en lecture seule, mais il est en fait dérivé du ControllerContext, que vous pouvez définir.

 controller.ControllerContext = new ControllerContext( context.Object, new RouteData(), controller );

0 votes

Celle-ci a fonctionné pour moi en me permettant de définir un HttpContext fictif sur le contrôleur.

43voto

0100110010101 Points 1727

Créez une requête, une réponse et placez-les toutes les deux dans HttpContext :

HttpRequest httpRequest = new HttpRequest("", "http://mySomething/", "");
StringWriter stringWriter = new StringWriter();
HttpResponse httpResponse = new HttpResponse(stringWriter);
HttpContext httpContextMock = new HttpContext(httpRequest, httpResponse);

0 votes

La question concerne les classes *Base, c'est-à-dire HttpRequestBase, et non HttpRequest - je ne sais pas trop pourquoi les deux sont nécessaires et il est encore plus ennuyeux qu'elles soient "scellées". Pas moyen de définir LogonUserIdentity :(

0 votes

S'ils sont marshallés ma référence, c'est toujours possible via le remoting, donc ça ne devrait pas être un problème.

1 votes

@ChrisKimpton : En dernier recours, il y a toujours réflexion ;-)

7voto

Xolartek Points 21

Voici comment j'ai utilisé le ControllerContext pour passer un faux chemin d'accès à l'application :

[TestClass]
public class ClassTest
{
    private Mock<ControllerContext> mockControllerContext;
    private HomeController sut;

    [TestInitialize]
    public void TestInitialize()
    {
        mockControllerContext = new Mock<ControllerContext>();
        sut = new HomeController();
    }
    [TestCleanup]
    public void TestCleanup()
    {
        sut.Dispose();
        mockControllerContext = null;
    }
    [TestMethod]
    public void Index_Should_Return_Default_View()
    {

        // Expectations
        mockControllerContext.SetupGet(x => x.HttpContext.Request.ApplicationPath)
            .Returns("/foo.com");
        sut.ControllerContext = mockControllerContext.Object;

        // Act
        var failure = sut.Index();

        // Assert
        Assert.IsInstanceOfType(failure, typeof(ViewResult), "Index() did not return expected ViewResult.");
    }
}

1 votes

Pourquoi faut-il passer un faux chemin d'accès à la demande ?

0 votes

Le code MVC l'exécutera et lancera une exception null s'il n'est pas présent.

5voto

Dinis Cruz Points 1042

Voici un exemple de ce que vous pouvez faire : Mocking HttpContext HttpRequest et HttpResponse pour les tests unitaires (en utilisant Moq)

Notez les méthodes d'extension qui aident vraiment à simplifier l'utilisation de cette classe de mocking :

var mockHttpContext = new API_Moq_HttpContext();

var httpContext = mockHttpContext.httpContext();

httpContext.request_Write("<html><body>".line()); 
httpContext.request_Write("   this is a web page".line());  
httpContext.request_Write("</body></html>"); 

return httpContext.request_Read();

Voici un exemple d'écriture d'un test unitaire utilisant moq pour vérifier qu'un module HttpModule fonctionne comme prévu : Test unitaire pour le module HttpModule utilisant Moq pour envelopper HttpRequest

Mise à jour : cette API a été remaniée pour devenir

0 votes

Les liens sont rompus - veuillez inclure le code dans votre réponse

2voto

ciscoheat Points 1211

Voici un cours qui pourrait vous être utile. Elle gère les requêtes ajax, l'authentification de l'utilisateur, les paramètres de la requête, etc : https://gist.github.com/3004119

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