Модульное тестирование статического метода, который вызывает статический метод с использованием moq - PullRequest
0 голосов
/ 14 сентября 2011

Как заголовок, сам код следующий

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 ]

3 голосов
/ 14 сентября 2011

Как насчет того, чтобы разделить метод на два - один из которых принимает "базовый 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;
    }
}

Затем вы можете проверить логику вперегрузка с тремя параметрами, но публичный метод на самом деле не содержит никакой логики.Вы не получите 100% покрытия, но сможете проверить реальную логику .

2 голосов
/ 14 сентября 2011

Вы не можете сделать это с Moq, потому что вам нужно было бы перехватить вызов методов этого статического класса, и это то, чего не могут достичь все "нормальные" среды моделирования, потому что они работают исключительно с наследованием типов , автоматическая генерация кода и тому подобное.
Однако для перехвата вызова статического метода нужны другие механизмы.
Перехват вызовов статических классов .NET Framework может быть выполнен с использованием Moles . Я не уверен, работает ли он с вашими статическими классами.
TypeMock Isolator работает со всеми статическими классами, но не является бесплатным.

Однако я действительно считаю, что вам следует пересмотреть свою архитектуру.

0 голосов
/ 14 сентября 2011

Я не уверен, что это возможно через Moq, я использую Rhino Mocks. В этой ситуации я обычно использую Spring.NET и предоставляю альтернативный макет, который я вызываю в тестах, а не в производственном. Это очень хорошо работает для меня, особенно в тех областях, где используются внешние веб-сервисы, источники данных или ситуация, которую вы подняли.

Затем вы выполните модульное тестирование 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>

Вы можете загрузить среду Spring.NET с http://www.springframework.net/

...