2016-10-17 2 views
1

필자는이 함수를 사용하여 이전 프로젝트에 단위 테스트를 추가하려고합니다. 나는파일을 읽는 정적 함수에 대한 단위 테스트

public static string GetDefaultName(bool isResponsive) 
    { 
     //Read web.config file 
     Configuration configuration = WebConfigurationManager.OpenWebConfiguration(System.Web.HttpContext.Current.Request.ApplicationPath); 
     if (!isResponsive) 
     { 
      if (configuration.AppSettings.Settings.AllKeys.Contains("defaultTheme")) 
      { 
       return configuration.AppSettings.Settings["defaultTheme"].Value; 
      } 
      else 
       return "default"; 
     } 
     else 
     { 
      // ... 
     } 
    } 

... 질문은 바보 같은 경우 단위 테스트에서 초보자가 그렇게 용서 그리고 난이 방법의 단위 테스트 작성하려고 해요 :

[TestMethod] 
    public void ReturnDefaulThemeNametIfThemeIsResponsive() 
    { 
     var theme = new Theme {isResponsive = true}; 

     var defaultName = Themes.GetDefaultName(theme.isResponsive); 
     Assert.AreEqual(defaultName, "defaultThemeResponsive"); 
    } 

내가 무엇을 궁금해을 이 정적 함수를 테스트하는 가장 좋은 방법이며 web.config 파일을 읽은 부분을 조롱하는 방법은 무엇입니까?

+1

현재 'web.config' 독서 물건을 조롱 할 수 없습니다. 접근 방법이 메소드 자체 내에서 발생하기 때문입니다. 필자는이 메서드를 매개 변수로 사용하여 종속성을 가져 오는 리팩터링을 고려할 것입니다. 그런 다음 그들을 조롱 할 수 있습니다. 당신이 할 수있는 또 다른 유일한 일은 유닛 테스트 프로젝트의'app.config' 파일을 업데이트하는 것이지만, 테스트의 설정 서브 시스템을 테스트하는 것입니다 (모든 의도와 목적이 어플리케이션의 설정과 똑같이 작동해야합니다). 서브 시스템). –

답변

1

(컴파일되지 않습니다,하지만 당신은 아이디어를 얻을 수 있습니다). 그러나이 경우에는 가능합니다. 리팩토링을해야 할 것입니다.

먼저 구성에 액세스하기 위해 모든 통화를 추상화해야합니다.

public interface IThemeSettings { 
    bool Contains(string key); 
    string this[string key] { get; } 
} 

그런 다음 종속성이 추상화를 사용하는 정적 테마 유틸리티 클래스를 업데이트 할 수 있습니다

[TestMethod] 
public void ReturnDefaulThemeNametIfThemeIsResponsive() { 
    //Arrange 
    var key = "defaultTheme"; 
    var expected = "defaultThemeResponsive"; 

    var mockSettings = new Mock<IThemeSettings>(); 
    mockSettings.Setup(m => m.Contains(key)).Returns(true); 
    mockSettings.Setup(m => m[key]).Returns(expected); 

    //In production you would also do something like this with 
    //the actual production implementation, not a mock 
    Themes.Configure(() => mockSettings.Object); 

    var theme = new Theme { isResponsive = true }; 

    //Act 
    var defaultName = Themes.GetDefaultName(theme.isResponsive); 

    //Assert 
    Assert.AreEqual(expected, defaultName); 
} 

을 테스트 할 때 당신은 지금 모의 객체를 사용하는 유틸리티를 구성 할 수 있습니다 와트를

public static class Themes { 
    private static IThemeSettings themes; 

    public static void Configure(Func<IThemeSettings> factory) { 
     if (factory == null) throw new InvalidOperationException("Must provide a valid factory method"); 
     themes = factory(); 
    } 

    public static string GetDefaultName(bool isResponsive) { 
     if (themes == null) throw new InvalidOperationException("Themes has not been configured."); 
     string result = string.Empty; 
     if (!isResponsive) { 
      if (themes.Contains("defaultTheme")) { 
       result = themes["defaultTheme"]; 
      } else 
       result = "default"; 
     } else { 
      // ... 
     } 
     return result; 
    } 

    //... 
} 

이 경우 나는 조롱 프레임 워크로 Moq를 사용했다.

몇 가지 조언. 수업을 HttpContext에 단단히 결합시키지 마십시오. 클래스는 추상화에 의존해야하며 Concretion에는 의존해서는 안됩니다.

1

방법은 현재 설계된 방식으로 구성 파일을 읽는 부분을 조롱 할 수 없습니다. 당신이 그것을 할 수 있기를 원한다면 그것을 당신의 방법에 대한 매개 변수로 만들 필요가있다. 즉 쉽게하는 방법 중 하나는이를 구현하는 설정 관리자 클래스의 Configuration 객체를 포장

public interface ISetting 
{ 
    string GetConfigItem(string itemName); 
} 

같은 인터페이스를 정의하는 것이다.

public class MySettings:ISetting 
{ 
    public string GetConfigItem(string ItemName) 
    { 
     // return value of the setting. In your case code that gets value of "defaultTheme" 
    } 
} 

사용자의 메서드는 이제 ISetting에 종속됩니다. 당신이 인터페이스를 구현하는 모의를 만들 수 있습니다 이제까지 당신이 지금 단위 테스트를 만들 수있는이 가진 현재의 상태와 web.config

public class SettingsTestHelper:ISetting 
{ 
    private _valueToReturn; 
    public SettingsTestHelper(string valueToReturn) 
    { 
     _valueToReturn=valueToReturn; 
    } 
    public string GetConfigItem(string itemName) 
    { 
     return valueToReturn; 
    } 
} 

의 콘텐츠를 독립적으로 원하는 가치를 무엇을 반환합니다 테스트를 위해

나는 그들이 단위 테스트하기 어려운로 종속성이 정적 유틸리티 멀리하려고

[TestMethod] 
public void CanGetSetting() 
{ 
    var helper = new SettingsTestHelper("default"); 
    var result = ClasThatImplementsYourStaticMethod.GetDefaultName(helper, true); 
    Assert.AreEqual(expected, actual); 
} 
관련 문제