2009-10-03 3 views
1

확장 방법이 있습니다. 아무도 Moq로이 방법을 테스트하는 방법을 알려 줄 수 있습니까?URLHelp를 사용하여 정적 클래스에서 정적 메서드를 조롱하는 방법은 무엇입니까? (Moq)

public static string GetBaseUrl(this UrlHelper urlHelper) 
    { 
     Uri contextUri = new Uri(urlHelper.RequestContext.HttpContext.Request.Url, urlHelper.RequestContext.HttpContext.Request.RawUrl); 
     UriBuilder realmUri = new UriBuilder(contextUri) { Path = urlHelper.RequestContext.HttpContext.Request.ApplicationPath, Query = null, Fragment = null }; 
     string url = realmUri.Uri.AbsoluteUri; 

     if (url.EndsWith("/")) 
     { 
      url = url.Remove(url.Length - 1, 1); 
     } 

     return url; 
    } 

감사합니다.

답변

1

TrueWill이 지적했듯이 가상이 아니기 때문에 Moq를 UrlHelper.RequestContext와 함께 직접 사용할 수 없습니다. 반면, UrlHelper는 유닛 테스트에 사용할 수 있도록 인스턴스화 할 수있는 공용 클래스입니다.

그러나 어떤 시점에서는 UrlHelper를 만들기 위해 HttpContextBase를 할당해야하며 Moq이이를 수행하는 데 도움을 줄 수 있습니다. 여기

내가 적어도 예외 던지는없이 GetBaseUrl를 호출하는 단위 테스트를 쓸 수 있는지 보여줍니다 테스트이다 : 그러나

[TestMethod] 
public void Test1() 
{ 
    var httpCtxStub = new Mock<HttpContextBase>(); 
    httpCtxStub.SetupGet(x => x.Request).Returns(() => 
     { 
      var reqStub = new Mock<HttpRequestBase>(); 
      reqStub.SetupGet(r => r.RawUrl).Returns("http://foo"); 
      reqStub.SetupGet(r => r.Url).Returns(new Uri("http://foo")); 
      return reqStub.Object; 
     }); 

    var requestCtx = new RequestContext(httpCtxStub.Object, new RouteData()); 
    var urlHelper = new UrlHelper(requestCtx, new RouteCollection()); 

    var result = urlHelper.GetBaseUrl(); 

    // Assert something 
} 

을,이 때문에, 작성하고 유지하기 위해 간단한 단위 테스트하지 않습니다 인터페이스 뒤에 UrlHelper를 숨기면 삶을 더 단순하게 만들 수 있다고하는 TrueWill의 의견을지지합니다.

+0

+1 : 내 대답보다 나은 대답. – TrueWill

+0

고맙습니다. –

+0

인터페이스를 사용하여이 podcast에서 게이트웨이 패턴을 사용하여 종속성을 분리하는 방법에 대한 좋은 토론이 있습니다. http://www.slickthought.net/post/2009/04/03/New-Spaghetti-Code-Podcast-ndash3b-Donn -Felker-Talks-Mocking.aspx – TrueWill

1

UrlHelper.RequestContext 속성은 가상이 아닙니다. Moq은 나의 지식의 최대에,이 경우에는 도움이되지 않을 것입니다.

인터페이스를 구현하는 UrlHelper에 대한 래퍼 클래스를 만들 수는 있지만 확장 메서드를 사용하는 목적을 무력화시키는 것처럼 보일 수 있습니다.

Typemock 상업 프로그램 예산이있는 경우 원하는대로 할 수 있습니다. (나는 그것을 시도하지 않고 직접 Moq을 사용한다.)

또 다른 옵션은이 방법에 대한 통합 테스트를 작성하는 것이다. 단위 테스트보다 느리게 실행되지만이 방법은 자주 버전을 설치하지 않을 것으로 판단됩니다.

큰 문제는 응용 프로그램의 나머지 부분에서 테스트 가능성을 줄이는 UrlHelper와의 연결입니다. 아마도 다른 포스터가 그 문제에 대한 해답을 제시 할 수 있습니다.

+0

+1 인터페이스 뒤에 UrlHelper를 숨기는 것이 좋습니다. –

관련 문제