Moq를 사용하여 ASP.NET MVC에서 HttpContext를 어떻게 모의합니까?


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

내 기본 컨트롤러에는이 requestContext를 가져 오는 Initialize의 재정의가 있습니다. 나는 이것을 전달하려고 노력하고 있지만 옳은 일을하고 있지 않습니다.

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

Moq를 사용하여 RequestContext 및 HttpContext를 조롱하는 방법에 대한 자세한 정보는 어디에서 얻을 수 있습니까? 나는 쿠키와 일반적인 맥락을 모의하려고 노력하고 있습니다.

답변:


61

HttpContext는 읽기 전용이지만 실제로는 설정할 수있는 ControllerContext에서 파생됩니다.

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

이것은 컨트롤러에 모의 HttpContext를 설정할 수 있도록 허용함으로써 나를 위해 일했습니다.
Joel Malone

39

요청, 응답을 생성하고 둘 다 HttpContext에 넣습니다.

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

문제는 * Base 클래스, 즉 HttpRequest가 아닌 HttpRequestBase에 관한 것입니다. 두 가지 모두 왜 나 자신이 필요한지 확실하지 않고 "봉인"되어 더 성가신 것입니다. LogonUserIdentity를 설정할 방법이 없습니다. :(
Chris Kimpton

그들이 내 참조를 마샬링하면 원격을 통해 여전히 가능하므로 문제가되지 않아야합니다.
0100110010101

1
@ChrisKimpton는 : 최후의 수단으로, 항상 거기에 반사 ;-)
올리버

다음과 같이 컨트롤러에 연결할 때 작동합니다. controller.ControllerContext = new ControllerContext (new HttpContextWrapper (httpContextMock), new RouteData (), controller);
Andreas Vendel 2014-06-25

예. 실제로 .LogonUserIdentity-_request.Setup (n => n.LogonUserIdentity) .Returns ((WindowsIdentity.GetCurrent));
KevinDeus 2014 년

12

감사합니다 사용자 0100110010101.

그것은 나를 위해 일했으며 아래 코드에 대한 테스트 케이스를 작성하는 동안 문제가 발생했습니다.

 var currentUrl = Request.Url.AbsoluteUri;

그리고 여기에 문제를 해결 한 라인이 있습니다

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

다른 사람들에게 도움이 될 수 있습니다.


HttpRequest 유형을 사용할 수없는 것 같습니다. 이제 다른 것이 있습니까?
Vincent Buscarello

1
이것은 HttpRequest의 모든 필드가 변경 불가능하기 때문에 유용하지 않습니다
A br

5

ControllerContext를 사용하여 가짜 애플리케이션 경로를 전달하는 방법은 다음과 같습니다.

[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
가짜 애플리케이션 경로를 전달해야하는 이유는 무엇입니까?
the_law

MVC 코드는이를 실행하고없는 경우 null 예외를 발생시킵니다.
Joshua Ramirez

5

다음은이를 설정하는 방법의 예입니다. Mocking HttpContext HttpRequest 및 UnitTests 용 HttpResponse (Moq 사용)

이 모의 클래스의 사용을 단순화하는 데 도움이되는 확장 메서드에 유의하십시오.

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

다음은 moq를 사용하여 단위 테스트를 작성하여 HttpModule이 예상대로 작동하는지 확인하는 방법의 예입니다. HttpRequest를 래핑하기 위해 Moq를 사용하여 HttpModule에 대한 단위 테스트

업데이트 :이 API는 다음으로 리팩터링되었습니다.


링크가 깨졌습니다. 답변에 코드를 포함 해주세요
Hades
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.