单元测试使用moq调用静态方法的静态方法

时间:2011-09-14 09:47:44

标签: c# unit-testing nunit moq static-methods

作为标题,代码本身如下

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 个答案:

答案 0 :(得分:3)

如何将方法拆分为两个 - 其中一个采用“基本URI”和“默认URL”,其中一个不采用:

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

然后你可以在“三参数”重载中测试逻辑,但是public方法实际上并不包含任何逻辑。您将无法获得100%的覆盖率,但您将能够测试所涉及的真实逻辑

答案 1 :(得分:2)

你不能用Moq做这个,因为你需要拦截对这个静态类的方法的调用,这是所有“普通”模拟框架无法实现的东西,因为它们纯粹是与类型继承一起工作的,自动代码生成和类似的东西 但是,拦截对静态方法的调用需要其他机制 可以使用Moles拦截对.NET框架静态类的调用。我不确定它是否适用于你自己的静态类 TypeMock Isolator适用于所有静态类,但它不是免费的。

但是,我真的认为,你应该重新考虑你的架构。

答案 2 :(得分:0)

我不确定Moq是否可以使用Rhino Mocks。我在这种情况下通常做的是使用Spring.NET并提供一个替代模拟,我在测试中调用它作为生产中的模拟。这对我来说非常有用,特别是对于使用外部Web服务,数据源或您已经提出的情况的区域。

然后单独测试 ImageRetrievalConfiguration 并确保其按预期工作。 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/

下载Spring.NET框架
相关问题