web-dev-qa-db-fra.com

Comment mocker 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 priorité sur l'initialisation qui obtient ce requestContext. J'essaie de transmettre cela, mais je ne fais pas quelque chose de bien.

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

Où puis-je obtenir plus d'informations sur la simulation de mon RequestContext et HttpContext à l'aide de Moq? J'essaie de me moquer des cookies et du contexte général.

94
Geo

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

Créez une demande, une réponse et mettez-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);
33
0100110010101

Merci utilisateur 0100110010101.

Cela a fonctionné pour moi et ici j'ai eu un problème lors de l'écriture du testcase pour le code ci-dessous:

 var currentUrl = Request.Url.AbsoluteUri;

Et voici les lignes qui ont résolu le problème

HomeController controller = new HomeController();
//Mock Request.Url.AbsoluteUri 
HttpRequest httpRequest = new HttpRequest("", "http://mySomething", "");
StringWriter stringWriter = new StringWriter();
HttpResponse httpResponse = new HttpResponse(stringWriter);
HttpContext httpContextMock = new HttpContext(httpRequest, httpResponse);
controller.ControllerContext = new ControllerContext(new HttpContextWrapper(httpContextMock), new RouteData(), controller);

Pourrait être utile pour les autres.

10
Chandan Kumar

Voici un exemple de la façon dont vous pouvez configurer cela: Mocking HttpContext HttpRequest et HttpResponse pour UnitTests (en utilisant Moq)

Notez les méthodes d'extension qui aident vraiment à simplifier l'utilisation de ces classes de simulation:

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 de la façon d'écrire un test unitaire en utilisant moq pour vérifier qu'un HttpModule fonctionne comme prévu: test unitaire pour HttpModule en utilisant Moq pour encapsuler HttpRequest

Mise à jour: cette API a été refactorisée en

5
Dinis Cruz

Voici comment j'ai utilisé le ControllerContext pour passer un faux chemin d'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.");
    }
}
4
Xolartek