7

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

4

6 回答 6

11

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

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

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

于 2012-05-28T20:01:43.220 回答
2

上面提供了很好的解决方案。为了完整起见,我已经使用这种技术一段时间了(使用 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);
    }
}
于 2019-11-27T15:43:30.667 回答
1

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

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

于 2012-05-28T19:39:47.317 回答
1

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

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

看看这个问题。一个更不受欢迎的答案:

单元测试和检查私有变量值

于 2012-05-28T19:47:53.573 回答
1

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

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

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

于 2018-08-24T01:54:31.527 回答
0

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

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

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

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

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

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

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

于 2021-05-01T21:13:13.923 回答