【问题标题】:Testing a private field using MSTest使用 MSTest 测试私有字段
【发布时间】:2012-05-28 19:36:20
【问题描述】:

是否可以在单元测试中访问私有字段?

【问题讨论】:

    标签: c# mstest


    【解决方案1】:

    上面提供了很好的解决方案。为了完整起见,我已经使用这种技术一段时间了(使用 MSTest),但也将它扩展到属性值。

    [ExcludeFromCodeCoverage]
    public static class TestExtensionMethods
    {
        public static T GetFieldValue<T>(this object sut, string name)
        {
            var field = sut
                .GetType()
                .GetField(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    
            return (T)field?.GetValue(sut);
        }
    
        public static T GetPropertyValue<T>(this object sut, string name)
        {
            var field = sut
                .GetType()
                .GetProperty(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    
            return (T)field?.GetValue(sut);
        }
    }
    

    【讨论】:

    • 这正是我所需要的。谢谢。
    【解决方案2】:

    获取私有字段或方法的方式一般是使用反射。但是,单元测试框架包含一个帮助器类PrivateObject,以使这更容易。请参阅docs。一般来说,当我使用它时,我最终制作了如下扩展方法:

    public static int GetPrivateField(this MyObject obj)
    {
      PrivateObject po = new PrivateObject(obj);
      return (int)po.GetField("_privateIntField");
    }
    

    但是,如果您需要在静态类中获取私有字段,则需要直接进行反射。

    【讨论】:

    • 您可以使用PrivateType 对象(与 PrivateObject 类型相反!)在静态类中获取和设置私有字段!
    【解决方案3】:

    测试是为了发现缺陷,而 TDD 是为了尽早发现缺陷。您需要与代码中的圈复杂度一样多的测试条件。超过一定量的复杂度很难调试;这就是为什么我们将复杂的任务分解为不太复杂的功能。一些公共任务需要大量的整体复杂性,而将复杂性划分为更小的例程可以更好地管理这种复杂性。现在,当您可以为较低级别的函数编写更简单的测试时,为什么还要在较高级别的函数中遭受测试条件的组合爆炸?

    您的方法是公开的还是私有的都没有关系。该方法的复杂性是其存在缺陷的可能性的最重要因素。如果您一次只需要测试一点复杂性,您会更快地发现和修复缺陷。

    假设您已将复杂的任务 A 分解为不太复杂的任务 X、Y 和 Z。如果您只在 A 进行测试,您会发现自己需要 X * Y * Z 测试条件而不是 X + Y + Z 条件。

    【讨论】:

      【解决方案4】:

      没有。如果您正在编写好的单元测试,则不需要访问任何私有字段。单元测试应该测试当传入一组已知值时,方法会以某种方式运行(通过返回适当的数据或以已知方式使用依赖项)。

      如果您尝试测试后者,请使用依赖注入将依赖注入到您正在测试的类中。您将可以完全访问这些依赖项以进行测试。

      【讨论】:

      • 谢谢你们,我没有意识到我违反了 TDD 原则。谢谢
      • 问题是它是否可能,而不是它是否是最佳实践。
      • 虽然我在理论上同意贾斯汀的观点,但在实践中,通常必须为无法更改或不易更改的次优代码编写单元测试。
      【解决方案5】:

      并不是说这是个好主意,但我已经看到 InternalsVisibleTo 使用过。

      http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

      看看这个问题。比较不受欢迎的答案之一:

      Unit testing and checking private variable value

      【讨论】:

        【解决方案6】:

        我知道这是旧的,但想在测试私有方法时增加我的 2 美分。

        我同意在大多数情况下测试面向公众的方法就足够了,但情况并非总是如此。

        我能想到两个例子,能够测试私有方法会很棒并且产生的测试更少。

        案例 1:报告:我有一个应用程序,它根据大量数据(接近 100 个数据点)生成报告。许多这些数据点依赖于一个或多个其他数据点。要确保每个代码路径都经过测试,需要进行 1000 次测试。

        案例 2:逻辑复杂的方法:我现在正在做一个项目,其中 3 或 4 个简短但复杂的逻辑块深埋在课堂上。能够对这些进行单元测试以开发它们会很方便。我是从另一种语言移植过来的,这些方法在 15 年多的时间里发生了变化。所以它们不会变脆。

        我尝试遵循 TDD 的 3 条法则,这对于很多私有方法来说真的很难做到。

        我只是说单元测试私有方法是可取的时间和原因。

        【讨论】:

          猜你喜欢
          • 2016-10-25
          • 1970-01-01
          • 2011-02-26
          • 2015-03-07
          • 2015-07-26
          • 2019-08-19
          • 2020-08-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多