Ваш метод имеет 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; чтобы решить эту зависимость, вы можете:
- передать его в качестве параметра метода
- сделать это поле вашего класса initilized во время строительства
Вы всегда можете обернуть 'ManagementObjectSearcher' в тонкий интерфейс, который автоматически сделает вашу зависимость прозрачной и легко заменяемой для другой реализации, например, тестовой ...Просто идея (и я нахожусь по телефону, так что это краток;)) –
Если вы используете .NET 4.0, взгляните на метод 'Environment.Is64BitOperatingSystem()' http://msdn.microsoft.com/ en-us/library/system.environment.is64bitoperatingsystem% 28VS.100% 29.aspx – bniwredyc
Отметьте [этот вопрос] (http://stackoverflow.com/q/336633/706456) – oleksii