Moq kullanarak ASP.NET MVC'de HttpContext ile nasıl alay edebilirim?


101
[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).
    ...
 }

benim temel denetleyicim bu requestContext'i alan Initialize için bir geçersiz kılmaya sahip. Bunu aktarmaya çalışıyorum ama bir şeyi doğru yapmıyorum.

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

Moq kullanarak RequestContext ve HttpContext'imle alay etme hakkında daha fazla bilgiyi nereden alabilirim? Çerezlerle ve genel bağlamla dalga geçmeye çalışıyorum.

Yanıtlar:


61

HttpContext salt okunurdur, ancak aslında ayarlayabileceğiniz ControllerContext'ten türetilmiştir.

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

Bu, denetleyicide sahte bir HttpContext ayarlamama izin vererek benim için çalıştı.
Joel Malone

39

Bir istek, yanıt oluşturun ve ikisini de HttpContext'e koyun:

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

Soru * Base sınıfları ile ilgili, yani HttpRequestBase, HttpRequest değil - neden her ikisine de ihtiyaç duyulduğundan emin değilim ve "mühürlenmiş" olduklarından daha da sinir bozucu. LogonUserIdentity'yi ayarlamanın yolu yok :(
Chris Kimpton

Referansıma göre sıralanırlarsa, uzaktan erişim yoluyla hala mümkündür, bu yüzden sorun olmamalı.
0100110010101

1
@ChrisKimpton: Son çare olarak, her zaman derinlemesine düşünme ;-)
Oliver

Bu, şu şekilde denetleyiciye eklenirken çalışır: controller.ControllerContext = new ControllerContext (new HttpContextWrapper (httpContextMock), new RouteData (), controller);
Andreas Vendel

Evet. gerçekten de ayarlayabilirsiniz .LogonUserIdentity - _request.Setup (n => n.LogonUserIdentity) .Returns ((WindowsIdentity.GetCurrent));
KevinDeus

12

0100110010101 kullanıcısına teşekkürler.

Benim için çalıştı ve burada aşağıdaki kod için test çantası yazarken bir sorun yaşadım:

 var currentUrl = Request.Url.AbsoluteUri;

Ve işte sorunu çözen satırlar

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

Diğerleri için yardımcı olabilir.


HttpRequest türünü kullanacak gibi görünmüyorum - bu şimdi başka bir şey mi?
Vincent Buscarello

1
Bu kullanışlı değildir çünkü HttpRequest'teki tüm alanlar değişmezdir
A br

6

Sahte bir Uygulama yolunu geçmek için ControllerContext'i şu şekilde kullandım:

[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
Neden sahte bir başvuru yolu geçmen gerekiyor?
the_law

MVC kodu onu çalıştıracak ve orada değilse boş bir istisna atacaktır.
Joshua Ramirez

5

Bunu nasıl ayarlayabileceğinize dair bir örnek: UnitTests için Mocking HttpContext HttpRequest ve HttpResponse (Moq kullanarak)

Bu alay sınıflarının kullanımını basitleştirmeye gerçekten yardımcı olan uzantı yöntemlerine dikkat edin:

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

Bir HttpModule'ün beklendiği gibi çalışıp çalışmadığını kontrol etmek için moq kullanarak Birim Testi yazmanın bir örneği: HttpRequest'i sarmak için Moq kullanarak HttpModule için Birim Testi

Güncelleme: bu API yeniden düzenlendi


Bağlantılar bozuk - lütfen cevabınıza kodu ekleyin
Hades
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.