2013-04-18 2 views
3

Я просматриваю модульные тесты нашего приложения и улучшаю/добавляю больше их. Я совершенно (нет, очень) новичок в модульном тестировании/тестировании, и я нашел следующий метод, который я хотел протестировать. Я застрял, и мой вопрос в том, есть ли способ переписать это так, чтобы это можно было проверить?Перезапись метода OS-запроса для проверки.

public static bool Is32BitOS() 
{ 
     string os = (from x in new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem").Get().OfType<ManagementObject>() 
        select x.GetPropertyValue("Caption")).First().ToString().Trim(); 

     if (os.Equals("Microsoft Windows XP Professional")) 
     { 
      return true; 
     } 

     if (os.StartsWith("Microsoft Windows 7")) 
     { 
      string architecture = (from x in new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem").Get().OfType<ManagementObject>() 
            select x.GetPropertyValue("OSArchitecture")).First().ToString(); 
      if (architecture == "64-bit") 
      { 
       return false; 
      } 
     } 

     return true; 
} 
+2

Вы всегда можете обернуть 'ManagementObjectSearcher' в тонкий интерфейс, который автоматически сделает вашу зависимость прозрачной и легко заменяемой для другой реализации, например, тестовой ...Просто идея (и я нахожусь по телефону, так что это краток;)) –

+2

Если вы используете .NET 4.0, взгляните на метод 'Environment.Is64BitOperatingSystem()' http://msdn.microsoft.com/ en-us/library/system.environment.is64bitoperatingsystem% 28VS.100% 29.aspx – bniwredyc

+0

Отметьте [этот вопрос] (http://stackoverflow.com/q/336633/706456) – oleksii

ответ

2

Ваш метод имеет 3 функции:

  1. Управления создание объектов поискового
  2. ОС и архитектура поиск
  3. проверка ОС

Чтобы включить тестирование, я бы добавить в AssemblyInfo .cs a строка, подобная этой:

[assembly: InternalsVisibleTo("Your.Test.Project")] 

так, чтобы защищенные методы были видны тестовому проекту, но не были свободно доступны для клиентов. Тогда я бы переписать метод так, что проверка ОС отделен:

//Acceptance test this method 
public static bool Is32BitOS() 
{ 
    var managementObjects = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem").Get().OfType<ManagementObject>(); 

    string os = (from x in managementObjects select x.GetPropertyValue("Caption")).First().ToString().Trim(); 
    string architecture = (from x in managementObjects select x.GetPropertyValue("OSArchitecture")).First().ToString(); 

    return Is32BitOS(os, architecture); 
} 

//Unit test this method 
internal static bool Is32BitOS(string os, string architecture) 
{ 
    if (os.Equals("Microsoft Windows XP Professional")) 
    { 
     return true; 
    } 

    if (os.StartsWith("Microsoft Windows 7")) 
    { 
     string architecture = archRetriever(); 
     if (architecture == "64-bit") 
     { 
      return false; 
     } 
    } 
    return true; 
} 

Теперь, когда мы выделили проблемы, я бы сказал, что ваш тест блока должен проверить только поведение Is32BitOs во время приемочных испытаний следует проверить от конца до конца. На самом деле у вас есть небольшое значение модульного тестирования, что

(from x in new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem").Get().OfType<ManagementObject>() 
select x.GetPropertyValue("Caption")).First().ToString().Trim(); 

извлекает строку Os в то время как ваша реальная ценность заключается в использовании этой информации, чтобы определить, если ОС 32 бит.

Альтернативой для обертывания интерфейсов и использования насмешливых фреймворков является применение функционального программирования here for Llewellyn Falco's peel and slice technique и here Arlo Belshee's no mocks approach. Таким образом, вместо того, чтобы метод, как:

public static bool Is32BitOS(IRetrieveOsAndArchitecture roa) 
{ 
    string os = roa.GetOs();     
    string architecture = roa.GetArchitecure(); 

    return Is32BitOS(os, architecture); 
} 

Вы могли бы использовать что-то вроде:

public static bool Is32BitOS(Func<ManagementObjectSearcher, string> osRetriever, 
          Func<ManagementObjectSearcher, string> archRetriever, 
          ManagementObjectSearcher searcher) 
{ 
    string os = osRetriever(searcher);    
    string architecture = archRetriever(searcher); 

    return Is32BitOS(os, architecture); 
} 

Его метода клиента будет:

public static bool Is32BitOS() 
{ 
    var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem"); 

    return Is32Bit((s)=>{ (from x in s.Get().OfType<ManagementObject>() select x.GetPropertyValue("Caption")).First().ToString().Trim()}, 
        (s)=>{ (from x in s.Get().OfType<ManagementObject>() select x.GetPropertyValue("OSArchitecture")).First().ToString();}, 
        searcher); 
} 

Обратите внимание, что во время тестирования случаев интерфейсов и функциональных вы не используете реальную внешнюю зависимость ManagementObjectSearcher; в поддельном подходе вы будете использовать макет объекта в функциональном программировании, который вы передадите в другом выражении лямбда, которое должно возвращать только строки os и архитектуры.

По-прежнему сохраняется ответственность за этот метод и является создание ManagementObjectSearcher; чтобы решить эту зависимость, вы можете:

  1. передать его в качестве параметра метода
  2. сделать это поле вашего класса initilized во время строительства

 Смежные вопросы

  • Нет связанных вопросов^_^