Я хочу создать общую функцию модульного теста, чтобы проверить все функции на основе параметра - PullRequest
0 голосов
/ 23 декабря 2010

Я хочу создать общую функцию модульного теста для проверки всех функций на основе параметра

, например,

commonmethod(string methodname,string paramter1,....)
{
....
}

какую логику я должен написать внутри этого метода, чтобы передать фактическуюфункция в параметре methodname, а затем общий метод должен выполнить эту функцию и вернуть результат.

Я использую структуру сущностей для всех функций, которые были созданы в моем проекте, и теперь я не хочу создавать отдельный модульпроверка функции для каждой функции. Просто одна функция должна выполнять работу на основе различных параметров ...

возможно ли это? .., если да, то, пожалуйста, предоставьте мне код для того же самого.

Ответы [ 4 ]

1 голос
/ 23 декабря 2010

Никогда не хорошо иметь логику в модульных тестах (переключаться, если, иначе, foreach, для, while), а также тип общего метода выполнения, который вы предлагаете, поскольку тест менее читабелен и, возможно, содержит скрытые ошибки. 1001 *

Множество простых, удобочитаемых и, следовательно, поддерживаемых тестов, каждый из которых тестирует только одну вещь, гораздо предпочтительнее одного теста с большой сложностью.

Я бы не стал использовать этот подход и иметь индивидуальный модульный тест для каждого сценария, который вы хотите проверить, в каждом тестируемом методе. В любом случае, юнит-тесты обычно занимают не более нескольких строк. И вы по-прежнему можете использовать тестовые среды (moq, moh rhino mocks) и повторно использовать заглушки, а также иметь некоторых основных помощников для облегчения жизни. Прежде всего важно, чтобы ваш код был тестируемым для начала.

0 голосов
/ 23 декабря 2010

@ Nilesh, если я правильно понимаю, следующий код должен быть идеальным для вас. Обратите внимание, что написанный ниже метод «CommonMethod» будет применим только для нестатических классов с конструктором без параметров и нестатических методов.

"TestClass" только для целей тестирования.

using System;
using System.Reflection;
using System.Collections;

namespace TestApp
{
    public class TestClass
    {
        public string MyMethod(string param1, string param2)
        {
            return (param1 + param2);
        }
    }

    public class DynaInvoke
    {
        /// 
        /// Method to invoke a method inside a class
        /// 
        /// Name of a non static class
        /// Name of a non static method
        /// Parameters required for the method
        /// result after execution of the method
        public object CommonMethod(string className, string methodName, object[] args)
        {
            Assembly ass = Assembly.GetCallingAssembly();
            object result = InvokeMethodSlow(ass.Location, className, methodName, args);
            return result;
        }


        // this way of invoking a function
        // is slower when making multiple calls
        // because the assembly is being instantiated each time.
        // But this code is clearer as to what is going on
        public static Object InvokeMethodSlow(string AssemblyName,
               string ClassName, string MethodName, Object[] args)
        {
            // load the assemly
            Assembly assembly = Assembly.LoadFrom(AssemblyName);

            // Walk through each type in the assembly looking for our class
            foreach (Type type in assembly.GetTypes())
            {
                if (type.IsClass == true)
                {
                    if (type.FullName.EndsWith("." + ClassName))
                    {
                        // create an instance of the object
                        object ClassObj = Activator.CreateInstance(type);

                        // Dynamically Invoke the method
                        object Result = type.InvokeMember(MethodName,
                          BindingFlags.Default | BindingFlags.InvokeMethod,
                               null,
                               ClassObj,
                               args);
                        return (Result);
                    }
                }
            }
            throw (new System.Exception("could not invoke method"));
        }

        // ---------------------------------------------
        // now do it the efficient way
        // by holding references to the assembly
        // and class

        // this is an inner class which holds the class instance info
        public class DynaClassInfo
        {
            public Type type;
            public Object ClassObject;

            public DynaClassInfo()
            {
            }

            public DynaClassInfo(Type t, Object c)
            {
                type = t;
                ClassObject = c;
            }
        }


        public static Hashtable AssemblyReferences = new Hashtable();
        public static Hashtable ClassReferences = new Hashtable();

        public static DynaClassInfo
               GetClassReference(string AssemblyName, string ClassName)
        {
            if (ClassReferences.ContainsKey(AssemblyName) == false)
            {
                Assembly assembly;
                if (AssemblyReferences.ContainsKey(AssemblyName) == false)
                {
                    AssemblyReferences.Add(AssemblyName,
                          assembly = Assembly.LoadFrom(AssemblyName));
                }
                else
                    assembly = (Assembly)AssemblyReferences[AssemblyName];

                // Walk through each type in the assembly
                foreach (Type type in assembly.GetTypes())
                {
                    if (type.IsClass == true)
                    {
                        // doing it this way means that you don't have
                        // to specify the full namespace and class (just the class)
                        if (type.FullName.EndsWith("." + ClassName))
                        {
                            DynaClassInfo ci = new DynaClassInfo(type,
                                               Activator.CreateInstance(type));
                            ClassReferences.Add(AssemblyName, ci);
                            return (ci);
                        }
                    }
                }
                throw (new System.Exception("could not instantiate class"));
            }
            return ((DynaClassInfo)ClassReferences[AssemblyName]);
        }

        public static Object InvokeMethod(DynaClassInfo ci,
                             string MethodName, Object[] args)
        {
            // Dynamically Invoke the method
            Object Result = ci.type.InvokeMember(MethodName,
              BindingFlags.Default | BindingFlags.InvokeMethod,
                   null,
                   ci.ClassObject,
                   args);
            return (Result);
        }

        // --- this is the method that you invoke ------------
        public static Object InvokeMethod(string AssemblyName,
               string ClassName, string MethodName, Object[] args)
        {
            DynaClassInfo ci = GetClassReference(AssemblyName, ClassName);
            return (InvokeMethod(ci, MethodName, args));
        }
    }
}

Следующий код демонстрирует, как использовать вышеуказанный код

                //Dynamic Invoke Test
                DynaInvoke dyn = new DynaInvoke();
                object[] args = {"My name is ", "Samar"};
                object result = dyn.CommonMethod("TestClass", "MyMethod", args);

Источник: Код проекта

0 голосов
/ 23 декабря 2010

commonmethod (строковое имя метода, строковый параметр1, ....) {....}

какую логику я должен написать внутри этого метода, чтобы передать действительную функцию

Вы хотите передать фактическую функцию , как указано в вашем описании, или имя функции, как указано в сигнатуре вашего метода?

Вы не сказали, в чем состоит ваше намерение (например, что вы пытаетесь выполнить), но если он вызывает вызываемый метод с заданным набором аргументов, чем как-то подтверждает результат, вы можете просто передать закрытие Например:

public static void commonmethod (Func<bool> test) {
   if (!test())
      testFailed();
}

...

Foo.commonmethod( ()=> someobject.foo(2,4) == 6 );
Foo.commonmethod( ()=> someobject.bar("zip", "zap") == "zip zap" );

Это в основном вызываемые объекты, которые инкапсулируют как метод, который вы хотите вызвать, так и аргументы.

0 голосов
/ 23 декабря 2010

Вы должны взглянуть на пространство имен System.Reflection. Объект MethodInfo имеет метод Invoke, который позволяет вам вызывать метод по имени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...