c# - 使用 NUnit 测试调用私有(private)方法的公共(public)方法

标签 c# unit-testing nunit private-members nmock

我在一个类中有一个公共(public)方法,它在内部调用该类中的一个特定私有(private)方法。它看起来像这样:

public class MyClass : IMyClassInterface
{
    public List<int> MyMethod(int a, int b)
    {
        MyPrivateMethod(a, b, ref varList, ref someVal);
    }
    private void MyPrivateMethod(int a, int b, ref List<int> varList, ref double someval)
    {
    }
}

现在,我基本上想使用 NUnit 测试这个公共(public)方法。我正在使用 NMock 2.0 进行模拟。我该怎么做?因为,它在内部调用了这个我不想公开的私有(private)方法。或者,如果我将私有(private)方法改为 protected ,是否有办法做到这一点?

最佳答案

Now, I basically want to test this public method (...)

这太棒了。这是你应该做的。暂时忘记内部细节。从公共(public)方法的角度来看,这两个片段之间有什么区别吗?

// Your current implementation
public void MyMethod(int a, int b)
{
    MyPrivateMethod(a, b);
}
private void MyPrivateMethod(int a, int b)
{
    var c = a + b;
    // some more code
}

// Private method inlined
public void MyMethod(int a, int b)
{
    var c = a + b;
    // some more code
}

调用(公共(public))MyMethod 的人将无法注意到这两者之间的任何区别。最终结果是一样的。有私有(private)方法调用并不重要,因为就公共(public) API 而言,它是无关紧要的。您可以内联所述私有(private)方法,使其永远消失,并且从公共(public)消费者的角度来看没有任何变化。最终结果是唯一重要的事情。您测试代码消费者可观察到的最终结果。不是一些内部乱码。

重要的实现是这样的:

Properly designed SOLID code will never put you in a position which will require you to do private mocking. Source of the problem? Bad design.

来源:How to mock private method - solutions

是的。悲伤但真实,你的设计不是那么好。根据您是否要更改它,您可以采取几种方法:

  • 不要试图模拟私有(private)细节,专注于公共(public) API(无助于解决设计问题)
  • 将私有(private)方法提取到类中,引入依赖关系(长期解决方案,改进设计并使代码易于测试)
  • 使私有(private)方法受到保护,按照其他答案中的建议在测试中覆盖(对设计问题没有帮助,可能不会产生有值(value)的测试)

无论你选择哪个,我都会留给你。但是,我会再强调一次 - 模拟私有(private)方法 不是单元测试、库或工具问题 - 它是一个设计问题,并且最好是这样解决的。


附带说明,(如果可以的话)不要使用 NMock2。这是一个自 2009 年以来的最后一次更改的图书馆。这就像一辆 30 年的旧车,上次维修是 15 年前。现在有更好的(FakeItEasy、Moq、NSubstitute)。

关于c# - 使用 NUnit 测试调用私有(private)方法的公共(public)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31308322/

相关文章:

c# - 为什么此 LINQ-to-SQL 查询会出现 NotSupportedException?

c# - 如何使用 C# 程序中的新值快速更新表中的所有行

c# - VSUTF、NUnit、xUnit.NET、MbUnit 与 SUTF 中的异步测试?

unit-testing - 试图了解 xunit 的历史

c# - 使用 LocalDB 进行集成测试

c# - 如何决定 Office 365 上的退回电子邮件?

c# - XPath 或,替代方案

javascript - TDD原理,如何让测试失败

unit-testing - 使用链接 : '<Link>s rendered outside of a router context cannot navigate.' 测试子组件

用于启用单元测试的Python包结构('Parent module not loaded'错误)