【问题标题】:How to test private variables in NUNit?如何在 NUUnit 中测试私有变量?
【发布时间】:2010-12-20 09:47:51
【问题描述】:

我有一个静态类,它有一个私有变量。

private static Dictionary<strng, string> items = new Dictionary<string, string>();

该类的许多公共方法都访问此字典对象。 现在我想编写 NUUnit 测试类(在不同的库中)。如何测试这个私有变量?

【问题讨论】:

    标签: unit-testing nunit


    【解决方案1】:

    我不会讨论你应该或不应该测试内部类的内部方法的天气。您可以公开您的内部方法/属性/类/等。通过使用InternalsVisibleToAttribute 属性到外部库。

    例如,如果您的单元测试库名为 MyUnitTestsLibrary,只需在项目(被测试的那个)的 AssemblyInfo.cs 文件中添加以下内容。

    [assembly:InternalsVisibleTo("MyUnitTestsLibrary")]
    

    这将使 MyUnitTestsLibrary 库成为您要测试的项目的朋友库,并公开它的所有内部内容,以便您进行单元测试。

    【讨论】:

    • 如果使用签名的程序集,这将导致痛苦的世界。
    • @eri0o 想扩展吗?我很想知道为什么这可能会导致问题发生
    【解决方案2】:

    我知道问题是关于 NUnit 的,我不想争论测试私有成员是好还是坏的做法。事实上,它有时是必要的,尤其是当您必须处理无法重构的遗留代码或设计不佳的代码时。

    所以我想提一下,Gallio/MbUnit 提供了一个名为 Mirror 的轻量级 API,以简化对私有类型成员的测试。


    示例:以下测试示例在 foo 实例上调用名为 SomePrivateMethod 的私​​有方法。

    [Test]
    public void SampleTest()
    {
       var foo = new Foo();
       int actual = Mirror.ForObject(foo)["SomePrivateMethod"].Invoke();
       Assert.AreEqual(123, actual);
    }
    

    【讨论】:

    • MSTest 通过其访问器提供相同的功能。但是单元测试仍然没有意义,因为你应该针对单元进行测试,而不是它的内部实现。
    【解决方案3】:

    你不测试私有变量,你测试类的行为。

    这意味着您应该只测试类的公共接口。

    另见this问题。

    【讨论】:

    • 感谢您的回答。但是,我发现很多人都支持双方关于“是否应该只测试公共接口或私有方法?”的辩论。所以如果我需要测试私有变量,有什么出路吗?..
    • 是的,你可以通过反射——例如——你可以绕过 C# 封装。也许 Yann 的回答可以帮助你。无论如何,如果我是你,我会寻找另一种方式。
    • Downvoted:Yann 的反应更好,这是无益且短视的,假设作者的观点是唯一的观点。
    【解决方案4】:

    在进行单元测试时,您应该测试公共接口,而不是私有实现。当您对其执行操作时,检查接口是否按预期运行,而不检查字典本身。这样,如果您将来决定用不同的数据结构替换 Dictionary,就不会破坏所有测试。

    【讨论】:

    • 感谢您的回答。但是,我发现很多人都支持关于“是否只应测试公共接口或私有方法?”的辩论双方。所以如果我需要测试私有变量,有什么出路吗?。
    • 如果你真的需要这样做,试试Yann的方法。但其背后的想法是,您的类与系统其余部分交互的唯一方式是通过其公共接口,所以这就是您需要测试的全部内容。您的类如何选择实现该接口取决于您,只要您通过公共接口履行义务。彻底的测试和对你的实现的测试是不必要且脆弱的(很容易因更改而崩溃)。
    猜你喜欢
    • 2017-07-23
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-27
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多