Поскольку я разрабатываю код, я часто хочу, чтобы блок тестировал некоторые из строительных блоков класса, даже если они обычно являются частными. Если мои модульные тесты находятся внутри проекта, я могу использовать «Друг» для выполнения этого и все еще сохраняю функции приватными для нормального использования. Но я предпочел бы переместить мои тесты NUnit в свои собственные отдельные проекты. Как достичь эффекта, который я ищу?Как я могу тестировать частные функции из отдельного проекта в VB .NET?
ответ
Вы не можете (легко) теста частные методов из другого проекта, но это довольно часто, чтобы проверить внутренних метод (Friend
в VB) из тестового проекта с использованием InternalsVisibleToAttribute
. Это делает доступными для другой сборки Friend
.
Видимо, это было ново в VB 9, хотя оно было доступно на C# 2 ... не совсем понятно почему, но this blog post from Bart de Smet дает быстрый пример.
Обратите внимание, что если ваша производственная сборка подписана, необходимо также подписать тестовую сборку, и вам нужно будет указать открытый ключ в аргументах InternalsVisibleToAttribute
. См. this Stack Overflow answer для более подробной информации.
Вы можете использовать Reflection для вызова частных методов. Для этого есть много образцов.
И именно это помогло мне больше всего: http://www.codeproject.com/KB/cs/testnonpublicmembers.aspx – demoncodemonkey
От быстрого поиска Google: http://www.codeproject.com/KB/cs/testnonpublicmembers.aspx
основы: (это приклеивается с сайта код проекта, связанного выше)
public static object RunStaticMethod(System.Type t, string strMethod,
object [] objParams)
{
BindingFlags eFlags =
BindingFlags.Static | BindingFlags.Public |
BindingFlags.NonPublic;
return RunMethod(t, strMethod,
null, aobjParams, eFlags);
} //end of method
public static object RunInstanceMethod(System.Type t, string strMethod,
object objInstance, object [] aobjParams)
{
BindingFlags eFlags = BindingFlags.Instance | BindingFlags.Public |
BindingFlags.NonPublic;
return RunMethod(t, strMethod,
objInstance, aobjParams, eFlags);
} //end of method
private static object RunMethod(System.Type t, string
strMethod, object objInstance, object [] aobjParams, BindingFlags eFlags)
{
MethodInfo m;
try
{
m = t.GetMethod(strMethod, eFlags);
if (m == null)
{
throw new ArgumentException("There is no method '" +
strMethod + "' for type '" + t.ToString() + "'.");
}
object objRet = m.Invoke(objInstance, aobjParams);
return objRet;
}
catch
{
throw;
}
} //end of method
Относительно того, почему это было ново в VB9, это была стоимость/выгодный компромисс. VB имеет совершенно другой способ разрешения имен, чем C# и InternalsVisibleTo очень усложняет поиск имени. Это было слишком дорого для VB8 и, следовательно, упало до VB9. Мы фактически вносим дальнейшие изменения вокруг разрешения имен в (продолжение) – JaredPar
(продолжение) для этого в VB10. – JaredPar
спасибо за этот ответ –