【问题标题】:unit testing static method C# program单元测试静态方法 C# 程序
【发布时间】:2018-08-23 06:57:33
【问题描述】:

我想对我的主程序的静态方法进行单元测试:

public class Program
{
    public static int Main(string[] args)
    { ... }
    private static bool TheAnswer(int ans)
    { 
        if (ans == 42)
            return true;
        return false;
     }
}

为了测试它,在我的单元测试项目中,我有:

var t = new PrivateType(typeof(Program));
bool result = Convert.ToBoolean(t.InvokeStatic("TheAnswer", 42));
Assert.AreEqual(result, true);

但这在调用 InvokeStatic 时失败了

“System.MissingMethodException”类型的异常发生在 mscorlib.dll 但未在用户代码中处理

附加信息:试图访问丢失的成员。

我怎样才能使这项工作(可以吗?)

堆栈跟踪: 'vstest.executionengine.x86.exe' (CLR v4.0.30319: UnitTestAdapter: Running test): 加载'C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO 14.0\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\TESTWINDOW\Extensions\Microsoft .VisualStudio.TestPlatform.Extensions.VSTestIntegration.dll'。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 'vstest.executionengine.x86.exe'(CLR v4.0.30319:UnitTestAdapter:运行测试):加载'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.QualityTools.UnitTestFramework\10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.QualityTools .UnitTestFramework.dll'。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 'vstest.executionengine.x86.exe'(CLR v4.0.30319:UnitTestAdapter:运行测试):加载'C:\Windows\Microsoft.Net\assembly\GAC_32\System.Data\v4.0_4.0.0.0__b77a5c561934e089\System.数据.dll'。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 “vstest.executionengine.x86.exe”(CLR v4.0.30319:UnitTestAdapter:运行测试):已加载“C:\Projects\myprogram\Test_the_test\bin\Debug\Test_the_test.dll”。已加载符号。 'vstest.executionengine.x86.exe'(CLR v4.0.30319:UnitTestAdapter:运行测试):加载'C:\Windows\Microsoft.Net\assembly\GAC_32\System.Transactions\v4.0_4.0.0.0__b77a5c561934e089\System.事务.dll'。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 “vstest.executionengine.x86.exe”(CLR v4.0.30319:UnitTestAdapter:运行测试):已加载“C:\Windows\Microsoft.Net\assembly\GAC_32\System.EnterpriseServices\v4.0_4.0.0.0__b03f5f7f11d50a3a\System。 EnterpriseServices.dll'。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 “vstest.executionengine.x86.exe”(CLR v4.0.30319:UnitTestAdapter:运行测试):已加载“C:\Windows\Microsoft.Net\assembly\GAC_32\System.EnterpriseServices\v4.0_4.0.0.0__b03f5f7f11d50a3a\System。 EnterpriseServices.Wrapper.dll'。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。 “vstest.executionengine.x86.exe”(CLR v4.0.30319:UnitTestAdapter:运行测试):已加载“C:\Projects\myprogram\Test_the_test\bin\Debug\myprogram.exe”。已加载符号。 抛出异常:mscorlib.dll 中的“System.MissingMethodException” 'vstest.executionengine.x86.exe'(CLR v4.0.30319:UnitTestAdapter:运行测试):加载'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.Debugger.Runtime\14.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Debugger .Runtime.dll'。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。

【问题讨论】:

  • 你应该问问自己测试私有方法是否合乎逻辑。
  • 根据定义,我相信你应该只测试公共方法。问问自己测试私有方法是否有意义。如果是这样,将其公开可能是个好主意。
  • 为什么不直接公开,直接调用呢?你的理由是什么?
  • 显而易见的解决方案是将其公开。
  • 这是一个可怕的原因。我可以通过学习如何将竹笋放在我的指甲下或射击自己的脚来“扩展我的知识”。但这没有任何意义。正如多次向您指出的那样,您应该对私有方法进行单元测试。这样做没有意义。学习真正有用的东西。不要学着做坏事。

标签: c# unit-testing private


【解决方案1】:

试试这个:

    object[] args = new object[1] { 42 };
    bool result = (bool)typeof(Program).InvokeMember(
                    name: "TheAnswer", 
                    invokeAttr: BindingFlags.NonPublic |
                                BindingFlags.Static |
                                BindingFlags.InvokeMethod,
                    binder: null, 
                    target: null, 
                    args: args);
Assert.AreEqual(result, true);

【讨论】:

  • 仍有缺失成员异常