Мне нравится проверять, является ли он iset и если он пуст в тройном операторе.
// POST variable check
$userID = (isset( $_POST['userID'] ) && !empty( $_POST['userID'] )) ? $_POST['userID'] : null;
$line = (isset( $_POST['line'] ) && !empty( $_POST['line'] )) ? $_POST['line'] : null;
$message = (isset( $_POST['message'] ) && !empty( $_POST['message'] )) ? $_POST['message'] : null;
$source = (isset( $_POST['source'] ) && !empty( $_POST['source'] )) ? $_POST['source'] : null;
$version = (isset( $_POST['version'] ) && !empty( $_POST['version'] )) ? $_POST['version'] : null;
$release = (isset( $_POST['release'] ) && !empty( $_POST['release'] )) ? $_POST['release'] : null;
При использовании .net необходимо использовать InternalsVisibleToAttribute.
CC -Dprivate=public
"CC" является компилятором командной строки в системе, которую я использую. -Dfoo=bar
делает эквивалент #define foo bar
. Так, этот параметр компиляции эффективно изменяет весь частный материал на общественность.
В редких случаях я хотел протестировать закрытые функции, я обычно изменял их, чтобы быть защищенным вместо этого, и я записал подкласс с общедоступной функцией обертки.
Класс:
...
protected void APrivateFunction()
{
...
}
...
Подкласс для тестирования:
...
[Test]
public void TestAPrivateFunction()
{
APrivateFunction();
//or whatever testing code you want here
}
...
Тесту MS создали хорошую функцию в этом, делает членов парламента, не занимающих официального поста и методы доступными в проекте путем создания файла, названного VSCodeGenAccessors
[System.Diagnostics.DebuggerStepThrough()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TestTools.UnitTestGeneration", "1.0.0.0")]
internal class BaseAccessor
{
protected Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject m_privateObject;
protected BaseAccessor(object target, Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType type)
{
m_privateObject = new Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject(target, type);
}
protected BaseAccessor(Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType type)
:
this(null, type)
{
}
internal virtual object Target
{
get
{
return m_privateObject.Target;
}
}
public override string ToString()
{
return this.Target.ToString();
}
public override bool Equals(object obj)
{
if (typeof(BaseAccessor).IsInstanceOfType(obj))
{
obj = ((BaseAccessor)(obj)).Target;
}
return this.Target.Equals(obj);
}
public override int GetHashCode()
{
return this.Target.GetHashCode();
}
}
С классами, которые получают из BaseAccessor
такой как
[System.Diagnostics.DebuggerStepThrough()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TestTools.UnitTestGeneration", "1.0.0.0")]
internal class SomeClassAccessor : BaseAccessor
{
protected static Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType m_privateType = new Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType(typeof(global::Namespace.SomeClass));
internal SomeClassAccessor(global::Namespace.Someclass target)
: base(target, m_privateType)
{
}
internal static string STATIC_STRING
{
get
{
string ret = ((string)(m_privateType.GetStaticField("STATIC_STRING")));
return ret;
}
set
{
m_privateType.SetStaticField("STATIC_STRING", value);
}
}
internal int memberVar {
get
{
int ret = ((int)(m_privateObject.GetField("memberVar")));
return ret;
}
set
{
m_privateObject.SetField("memberVar", value);
}
}
internal int PrivateMethodName(int paramName)
{
object[] args = new object[] {
paramName};
int ret = (int)(m_privateObject.Invoke("PrivateMethodName", new System.Type[] {
typeof(int)}, args)));
return ret;
}
На CodeProject существует статья, которая кратко обсуждает за и против тестирования закрытых методов. Это тогда обеспечивает некоторый отражательный код для доступа к закрытым методам (подобный коду, который Marcus обеспечивает выше.) Единственная проблема, которую я нашел с образцом, - то, что код не принимает во внимание перегруженные методы.
можно найти статью здесь:
Если Вы хотите к модульному тесту закрытый метод, что-то может быть неправильным. Модульные тесты (вообще говоря), предназначены для тестирования интерфейса класса, означая его общественность (и защищены), методы. Можно, конечно, "взломать" решение этого (даже если только, обнародовав методы), но можно также хотеть рассмотреть:
Объявите их internal
, и затем используйте InternalsVisibleToAttribute
, чтобы позволить Вашему блоку модульного теста видеть их.
Я склонен не использовать директивы компилятора, потому что они загромождают вещи быстро. Один способ смягчить его при реальной необходимости в них состоит в том, чтобы поместить их в частичный класс и иметь сборку, игнорируют что .cs файл при создании производственной версии.
Я также использовал метод InternalsVisibleToAttribute. Стоит упомянуть также, что, если Вы чувствуете себя, неловко делая Ваши ранее закрытые методы внутренними для достижения этого, тогда возможно, они не должны быть предметом прямых модульных тестов так или иначе.
, В конце концов, Вы тестируете поведение из Вашего класса, а не это определенная реализация - можно изменить последнего, не изменяя первого, и тесты должны все еще передать.
MbUnit получил красивую оболочку для этого под названием Reflector.
Reflector dogReflector = new Reflector(new Dog());
dogReflector.Invoke("DreamAbout", DogDream.Food);
Вы также можете устанавливать и получать значения из свойств.
dogReflector.GetProperty("Age");
Что касается «частного теста», я согласен, что ... в идеальном мире. нет смысла делать частные модульные тесты. Но в реальном мире вы, возможно, захотите написать частные тесты вместо рефакторинга кода.
Иногда бывает полезно проверить частные объявления. По сути, у компилятора есть только один открытый метод: Compile (string outputFileName, params строка [] sourceSFileNames). Я уверен, вы понимаете, что такой метод будет сложно протестировать, не проверяя каждое «скрытое» объявление!
Вот почему мы создали Visual T #: для упрощения тестов. Это бесплатный язык программирования .NET (совместимый с C # v2.0).
Мы добавили оператор '.-'. Просто веди себя как '.' оператор, за исключением того, что вы также можете получить доступ к любому скрытому объявлению из ваших тестов, ничего не меняя в тестируемом проекте.
Взгляните на наш веб-сайт: скачать это бесплатно .
Частные типы, внутренние и частные члены являются таковыми по какой-то причине, и часто вы не хотите связываться с ними напрямую. И если вы это сделаете, скорее всего, вы сломаетесь позже, потому что нет гарантии, что ребята, которые создали эти сборки, сохранят частные / внутренние реализации как таковые.
Но иногда, когда я выполнял некоторые хаки / исследования скомпилированных или сторонних сборок, я сам в конечном итоге хотел инициализировать частный класс или класс с частным или внутренним конструктором.Или, иногда, имея дело с предварительно скомпилированными устаревшими библиотеками, которые я не могу изменить - я заканчиваю тем, что пишу некоторые тесты против частного метода.
Так родился AccessPrivateWrapper - http://amazedsaint.blogspot.com/2010/05/accessprivatewrapper-c-40-dynamic.html - это класс быстрой оболочки, который сделает работу легко использовать динамические функции C # 4.0 и отражение.
Вы можете создавать внутренние / частные типы, например
//Note that the wrapper is dynamic
dynamic wrapper = AccessPrivateWrapper.FromType
(typeof(SomeKnownClass).Assembly,"ClassWithPrivateConstructor");
//Access the private members
wrapper.PrivateMethodInPrivateClass();
Вы можете сгенерировать тестовый метод для приватного метода из Visual studio 2008. Когда вы создаете модульный тест для частного метода, в ваш тестовый проект добавляется папка Test References и в эту папку добавляется аксессор. Аксессор также упоминается в логике метода модульного теста. Этот аксессор позволяет вашему модульному тесту вызывать частные методы в коде, который вы тестируете. Подробности смотрите на