2

我正在尝试对具有公共和私有方法的类进行单元测试,并且我想对已设置为私有的特定方法(基础上的受保护抽象)进行单元测试。我无法公开该方法,也不想通过整个过程来测试该方法,我只关心该方法的输入参数和返回是否符合预期。

我不想公开该方法,因为这个问题突出显示:

将私有方法公开以对其进行单元测试...好主意吗?

我的问题是,测试私有方法的各种方法是什么,我应该支持哪种技术,为什么?

我已阅读此问题(您如何对私有方法进行单元测试?)但想知道接受的答案是否仍然是最佳答案,或者多年后有更好的方法。

如果这个问题被认为是如何对私有方法进行单元测试?我将在那里添加我的评论并要求更新,请告知。

4

7 回答 7

6

如果您不能通过公共方法有意义地测试类的私有方法,那么这表明该类的设计有问题。如果很难测试类,以便您希望分解测试以测试其功能的子集,那么我建议将类分解为其逻辑部分并单独测试它们。

也许您有机会重构代码,以便私有方法成为其他一些类的公共方法。一个很好的例子是一个类,它在一个计时器上安排一些工作,以便稍后处理。工作方法可能会被实现为私有方法,如果不安排计时器并等待它执行工作方法,则很难以简单的方式进行测试。在执行时间应该非常快的测试中并不理想。解决此问题的一种简单方法是将调度工作代码拆分为两个单独的类。然后,私有工作方法成为 Worker 类的公共方法,使其非常容易测试。虽然拆分调度和工作代码意味着您将难以实现 100% 的覆盖率,但您至少会覆盖工作代码。

于 2013-05-30T10:27:19.863 回答
2

我已阅读此问题(您如何对私有方法进行单元测试?),但想知道接受的答案是否仍然是最佳答案,或者多年后有更好的方法。

我会避免接受的答案。

我可以长篇大论地测试公共接口而不担心内部,但这可能不现实。

我可以看到两个直接选项:

  • 反思看方法,有点像黑客,但至少你可以进行某种测试。这也可能是最容易快速开始工作的方法。
  • 使用类似策略模式的东西抽象私有方法行为,并将行为注入对象本身(或者让对象在内部new手动设置相关策略)。然后可以独立测试这个单独的策略项目。

也就是说,您不应该经常遇到这种情况。如果你这样做了,你需要退后一步,回顾你是如何设计你的课程的,并可能回顾它们,以使它们更加开放和可测试。

于 2013-05-30T10:27:15.853 回答
1

在 VS 2005、2008 和 2010 中,您可能拥有私有访问器。您右键单击一个私有函数,然后选择“创建私有访问器”...

在 VS 2012 中,这个功能不知何故消失了。唯一方便的方法是使用 PrivateObject。您可以查看 MSDN 以获取使用 PrivateObject 的示例。

于 2013-05-30T11:24:59.293 回答
0

如果您使用的是 VS 2005 或更高版本,请使用以下步骤

  1. 打开包含私有方法的源代码文件。
  2. 右键单击私有方法,然后选择创建单元测试。这将显示“创建单元测试”对话框。在可见的树结构中,仅选中了私有方法的复选框。
  3. (可选)在创建单元测试对话框中,您可以更改输出项目。您还可以单击设置来重新配置生成单元测试的方式。
  4. 单击确定。这将创建一个名为 VSCodeGenAccessors 的新文件,其中包含特殊的访问器方法,用于检索正在测试的类中私有实体的值。您可以在测试项目文件夹中的解决方案资源管理器中看到新文件。如果您的测试项目在此之前没有单元测试,则还会创建一个用于容纳单元测试的源代码文件。与包含私有访问器的文件一样,包含单元测试的文件也在解决方案资源管理器的测试项目中可见。
  5. 打开包含单元测试的文件并滚动到私有方法的测试。找到标有 // TODO: 注释的语句,并按照注释中的说明完成它们。这有助于测试产生更准确的结果

有关更多信息,请参阅

看起来它在内部使用反射来调用私有方法。但它有效。

于 2014-02-21T09:02:46.180 回答
0

您是否希望能够在测试中调用您的私有方法并查看它是如何工作的?

您可以从您的类派生并添加将调用您要测试的方法的公共方法。很简单。虽然我不建议测试私有方法。我想不出这样做的单一理由。我很想看到能改变我想法的例子。

编辑:由于这个答案仍然有一些流量,我分享了这个链接。这篇博文是在我发布答案大约 4 年后创建的: https ://enterprisecraftsmanship.com/posts/unit-testing-private-methods/

于 2013-05-30T12:02:31.750 回答
0

实际上,我来这里是为了回答这个问题,直到我意识到我不应该对私有方法进行单元测试。这样做的原因是,私有方法是进程中的一部分,是更大逻辑的一部分。

单元测试旨在针对类的接口进行测试。这个想法是,我应该在以预期的方式使用我的课程时确保质量控制。因此,对私有方法进行单元测试是没有用的,因为它永远不会暴露给消费者(无论是谁在实现)。您需要针对消费者可以使用您的课程的案例进行单元测试。

如果您发现自己绝对需要对私有的东西进行单元测试,您可能需要重新考虑该方法的位置,或者您的代码是如何分解的。我得出的结论是,如果我需要对私有方法进行单元测试,9/10 次它是可以包装到静态实用程序类中的方法。

于 2015-03-05T17:36:55.787 回答
0

使用反射。如果您不想自己弄乱反射,那么您可以使用位于 Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll 中的 Microsoft PrivateObject 类。但是 MSTest 和 NUnit 的配合存在问题——同时使用 MSTest 和 NUnit?

于 2013-05-30T10:44:39.657 回答