2011-09-14 48 views
0

正如標題調用一個靜態方法靜態方法,代碼本身如下單位測試使用起訂量

internal static class ThumbnailPresentationLogic 
    { 
     public static string GetThumbnailUrl(List<Image> images) 
     { 
      if (images == null || images.FirstOrDefault() == null) 
      { 
       return ImageRetrievalConfiguration.MiniDefaultImageFullUrl; 
      } 

      Image latestImage = (from image in images 
           orderby image.CreatedDate descending 
           select image).First(); 

      Uri fullUrl; 

      return 
       Uri.TryCreate(new Uri(ImageRetrievalConfiguration.GetConfig().ImageRepositoryName), latestImage.FileName, 
        out fullUrl) 
        ? fullUrl.AbsoluteUri 
        : ImageRetrievalConfiguration.MiniDefaultImageFullUrl; 
     } 
    } 

我不想單元測試經過任何方法ImageRetrievalConfiguration類,所以怎麼能我嘲笑ImageRetrievalConfiguration並將其傳入ThumbnailPresentationLogic類?

回答

3

你怎麼樣拆分方法分爲二 - 其中一個採用「基礎URI」和「默認網址」和其中一個不會:

internal static class ThumbnailPresentationLogic 
{ 
    public static string GetThumbnailUrl(List<Image> images) 
    { 
     return GetThumbnailUrl(images, 
      new Uri(ImageRetrievalConfiguration.GetConfig().ImageRepositoryName), 
      ImageRetrievalConfiguration.MiniDefaultImageFullUrl); 
    } 

    public static string GetThumbnailUrl(List<Image> images, Uri baseUri, 
     string defaultImageFullUrl) 
    { 
     if (images == null || images.FirstOrDefault() == null) 
     { 
      return defaultImageFullUrl; 
     } 

     Image latestImage = (from image in images 
          orderby image.CreatedDate descending 
          select image).First(); 

     Uri fullUrl; 

     return 
      Uri.TryCreate(baseUri, latestImage.FileName, out fullUrl) 
       ? fullUrl.AbsoluteUri 
       : defaultImageFullUrl; 
    } 
} 

然後你就可以在測試邏輯「三參數」重載,但公共方法並不包含任何邏輯。你不會得到100%的覆蓋率,但你將能夠測試涉及的真實的邏輯

2

你不能用Moq做到這一點,因爲你需要攔截對這個靜態類的方法的調用,這是所有「正常」的嘲諷框架無法實現的,因爲它們純粹用類型繼承,自動代碼生成和類似的東西。
但是,截取對靜態方法的調用需要其他機制。
攔截對.NET框架靜態類的調用可以使用Moles完成。我不確定它是否可以與你自己的靜態類一起工作。
TypeMock Isolator適用於所有靜態類,但它不是免費的。

但是,我真的認爲,你應該重新考慮你的架構。

0

我不確定通過Moq可以使用Rhino Mocks。我通常在這種情況下做的是使用Spring.NET,並提供了一個替代模擬,我在測試中將其稱爲生產中的一個。這對我來說真的很好,尤其是那些使用外部Web服務,數據源或您所提出情況的領域。

然後您再單元測試ImageRetrievalConfiguration seperatly並確保它按預期工作。 MockImageRetrievalConfiguration可以根據您希望在測試環境中做出反應的方式返回結果。這將最大限度地利用嘲笑的靈活性實現測試平衡。

internal static class SpringApplicationContext 
    { 
     private static IApplicationContext applicationContext = null; 

     static SpringApplicationContext() 
     { 
      applicationContext = ContextRegistry.GetContext(); 
     } 

     public static IApplicationContext ApplicationContext 
     { 
      get { return applicationContext; } 
     } 
    } 

    public interface IImageRetrievalData 
    { 
     string ImageRepositoryName{get;set;} 
    }  

public interface IImageRetrievalConfiguration  
{ 
    IImageRetrievalData GetConfig(); 
} 

public class MockImageRetrievalConfiguration : IImageRetrievalConfiguration  
{  
    public IImageRetrievalData GetConfig() 
    { 
     //mock implementation 
    } 
} 

public class ImageRetrievalConfiguration : IImageRetrievalConfiguration  
{ 

    public IImageRetrievalData GetConfig() 
    { 
     //Concrete implementation 
    } 
} 



//your code 
internal static class ThumbnailPresentationLogic  
{   
      public static string GetThumbnailUrl(List<Image> images) 
      {    
      if (images == null || images.FirstOrDefault() == null)           
      {     
       return ImageRetrievalConfiguration.MiniDefaultImageFullUrl;    
      }    
      Image latestImage = (from image in images orderby image.CreatedDate descending select image).First();    
      Uri fullUrl; 

//Spring 
       IImageRetrievalConfiguration imageRetrievalConfig = (IImageRetrievalConfiguration)   SpringApplicationContext.ApplicationContext["ImageRetrievalConfiguration"]; 



      return Uri.TryCreate(new Uri(imageRetrievalConfig.GetConfig().ImageRepositoryName), latestImage.FileName, out fullUrl) ? fullUrl.AbsoluteUri : ImageRetrievalConfiguration.MiniDefaultImageFullUrl;   
      }  
} 

//這將是您的測試配置

<spring> 
    <context> 
     <resource uri="config://spring/objects" /> 
    </context> 
    <objects xmlns="http://www.springframework.net"> 
     <object name="ImageRetrievalConfiguration" type="Tests.MockImageRetrievalConfiguration, Tests" singleton="false" /> 
    </objects> 
    </spring> 

//這將是您的生產配置

<spring> 
    <context> 
     <resource uri="config://spring/objects" /> 
    </context> 
    <objects xmlns="http://www.springframework.net"> 
     <object name="ImageRetrievalConfiguration" type="Web.ImageRetrievalConfiguration , Web" singleton="false" /> 
    </objects> 
    </spring> 

您可以從http://www.springframework.net/

+0

下載Spring.NET框架我修改了你提到的情況的代碼。這將導致具體的實現不會在測試中被調用,但仍然允許它是可測試的。 – Jonathan