开发者

I want to create a common unit test function to check all functions based on parameter

开发者 https://www.devze.com 2023-02-01 10:03 出处:网络
I want to create a c开发者_运维问答ommon unit test function to check all functions based on parameter

I want to create a c开发者_运维问答ommon unit test function to check all functions based on parameter

for e.g

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

what logic should i write inside this method so that by passing a actual function in parameter methodname and then the common method should execute that function and should return the output.

i am using entity framework for all functions which has been created in my project and now i dont want to create a separate unit test function for each function.just one function should do the job based on different parameters...

is that possible.. ?, if so then please provide me an code for same..


It's never good to have logic in units tests, (switch, if, else, foreach, for, while) and also the kind of common method runner you are suggesting as the test is less readable and possibly introduces hidden bugs.

Many simple, readable, and therefore maintainable tests that are only testing one thing each are far preferable to one test with a lot of complexity.

I would not go for this approach and have an individual unit test for each scenario you want to test, in each method under test. Unit tests are not normally more than a few lines each anyway. And you can still use test frameworks (moq, rhino mocks) and reuse stubs and have some basic helpers to make life easy. Most of all it is important your code is testable to begin with.


You should look at the System.Reflection name space. The MethodInfo object has an Invoke method that allows you to call a method by name.


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

what logic should i write inside this method so that by passing a actual function

Do you want to pass the actual function, as your description says, or the name of the function, as your method signature says?

You didn't say what your intent is (e.g. what you're trying to accomplish), but if it's to call the passed-in method with a given set of arguments than validate the result somehow, you can just pass in a closure. For instance:

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

These are basically callable objects which encapsulate both the method you want to call and the arguments.


@Nilesh if my understanding is correct the following code should be perfect for you. Note that the "CommonMethod" method written below will be applicable only for non static classes with parameterless constructor and non static methods.

The "TestClass" is just for testing purposes.

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

The following code demonstrates how to use the above code

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

Source: Code Project

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号