我想创建一个通用的单元测试函数来检查基于参数的所有函数

时间:2010-12-23 07:01:42

标签: c# asp.net linq unit-testing

我想创建一个通用单元测试函数来检查基于参数

的所有函数

例如

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

我应该在这个方法中编写什么逻辑,以便通过在参数methodname中传递一个实际函数,然后公共方法应该执行该函数并返回输出。

我正在为我的项目中创建的所有函数使用实体框架,现在我不想为每个函数创建单独的单元测试函数。只需要一个函数根据不同的参数完成工作......

是可能的吗??,如果是的话,请为我提供相同的代码..

4 个答案:

答案 0 :(得分:1)

在单元测试中有逻辑,(切换,if,else,foreach,for,while)以及你建议的常用方法运行器,因为测试的可读性较低,可能会引入隐藏的错误。< / p>

许多简单,可读且可维护的测试只测试一件事,远比一件复杂的测试更好。

我不会采用这种方法,并且在每个测试方法中对每个要测试的场景进行单独的单元测试。无论如何,单元测试通常不超过几行。你仍然可以使用测试框架(moq,rhino mocks)和重用存根,并有一些基本的帮助,使生活更轻松。最重要的是,您的代码一开始就是可测试的。

答案 1 :(得分:0)

您应该查看System.Reflection名称空间。 MethodInfo对象有一个Invoke方法,允许您按名称调用方法。

答案 2 :(得分:0)

  

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

     

我应该在这个方法中写什么逻辑,以便通过传递一个实际的函数

您是否希望传递实际功能,如您的说明所示,或者您的方法签名所示的名称

你没有说出你的意图(例如你想要完成的事情),但是如果用一组给定的参数调用传入方法而不是以某种方式验证结果,你可以直接传入关闭。例如:

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" );

这些基本上是可调用的对象,它们封装了你想要调用的方法和参数。

答案 3 :(得分:0)

@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);

来源:Code Project